gpt4 book ai didi

php - 功能测试 - 模拟服务不会持久存在于服务容器中

转载 作者:搜寻专家 更新时间:2023-10-31 21:12:45 27 4
gpt4 key购买 nike

我希望有人能阐明我面临的这个问题。

[问题]

我在功能单元测试中模拟了 doctrine.orm.default_entity_manager 服务。我将其注入(inject)到客户端服务容器中,这样我就不必在功能测试过程中访问我的数据库。对于仅涉及 GET 请求的测试,我能够验证我正在测试的 Controller 是否正在使用我的模拟服务。

但是,如果我尝试通过使用带有表单提交的爬虫来执行 POST 请求,我的模拟服务不会持续存在。在初始 GET 请求之后,客户端似乎只是在需要时再次注入(inject) 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

所以你需要在每次请求后用你的 mock 替换 doctrine:

// 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 中的 Doctrine 设置

 orm:
default_entity_manager: Acme/MyBundle/Test/MockDoctrineEM

http://symfony.com/doc/master/reference/configuration/doctrine.html

关于php - 功能测试 - 模拟服务不会持久存在于服务容器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15606191/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com