Функциональный тест – служба Mock не сохраняется в сервисном контейнере

Я надеюсь, что кто-то может пролить свет на этот вопрос, с которым я столкнулся.

[ПРОБЛЕМА]

Я издевался над службой 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

Поэтому вам нужно заменить доктрину своим макетом после каждого запроса:

 // 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