我希望有人能够对我面临的这个问题有所启发。
[问题]
我在功能单元测试中模拟了doctrine.orm.default_entity_manager 服务。我将其注入客户端服务容器中,这样我就不必在功能测试过程中访问我的数据库。对于仅涉及 GET 请求的测试,我能够验证我正在测试的控制器是否正在使用我的模拟服务。
但是,如果我尝试使用带有表单提交的爬网程序执行 POST 请求,我的模拟服务将不会持续存在。在初始 GET 请求之后,客户端似乎只是在需要时再次注入doctrine.orm.default_entity_manager 服务,而不是我在客户端服务容器中设置的模拟版本。
总之,在 GET 请求期间,正在使用我的模拟服务,但在 POST 请求期间,正在使用 EntityManager5144076565ee8_546a8d27f194334ee012bfe64f629947b07e4919__CG__\Doctrine\ORM\EntityManager 。[参见下面的代码片段]
[问题]
可以按照我的要求做吗?我想让我的所有请求都使用我定义的模拟服务。我想要进行功能测试,但避免从数据库写入或读取。
[示例代码]
// Mocks
$entityRepository = $this
->getMockBuilder('Doctrine\ORM\EntityRepository')
->setMethods(array('findby'))->disableOriginalConstructor()
->getMock();
$entityRepository->expects($this->any())->method('findBy')
->will($this->returnValue(array()));
$em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
->setMethods(
array('getRepository', 'getClassMetadata', 'flush',
'persist'))->disableOriginalConstructor()
->getMock();
$em->expects($this->any())->method('flush')
->will($this->returnValue(FALSE));
$em->expects($this->any())->method('persist')
->will($this->returnValue(FALSE));
$em->expects($this->any())->method('getRepository')
->will($this->returnValue($entityRepository));
$em->expects($this->any())->method('getClassMetadata')
->will($this->returnValue(new ClassMetadata("test")));
// Create test client.
$client = static::createClient();
// Inject entity mock into service container.
$client->getContainer()
->set('doctrine.orm.default_entity_manager', $em, 'container');
// Define request
$crawler = $client->request('GET', '/locations/types/add');
// Verify a few things
$form = $crawler->selectButton('submit')->form();
$form['location_type[title]'] = "TEST TITLE";
$form['location_type[description]'] = "TEST DESCP";
$crawler = $client->submit($form);
这里的问题是内核在每个请求之后(期间)启动:
protected function doRequest($request)
{
// avoid shutting down the Kernel if no request has been performed yet
// WebTestCase::createClient() boots the Kernel but do not handle a request
if ($this->hasPerformedRequest) {
$this->kernel->shutdown();
} else {
$this->hasPerformedRequest = true;
}
if ($this->profiler) {
$this->profiler = false;
$this->kernel->boot();
$this->kernel->getContainer()->get('profiler')->enable();
}
https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Client.php https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Client.php
因此,您需要在每次请求后用您的模拟替换教义:
// Inject entity mock into service container.
$client->getContainer()
->set('doctrine.orm.default_entity_manager', $em, 'container');
// Define request
$crawler = $client->request('GET', '/locations/types/add');
// Inject entity mock into service container.
$client->getContainer()
->set('doctrine.orm.default_entity_manager', $em, 'container');
全局使用模拟的一种更简单的方法是覆盖 config_test.yml 中的学说设置
orm:
default_entity_manager: Acme/MyBundle/Test/MockDoctrineEM
http://symfony.com/doc/master/reference/configuration/doctrine.html http://symfony.com/doc/master/reference/configuration/doctrine.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)