Я думаю, что частью проблемы является смешение стилей тестирования. У вас есть WebTestCase, который предназначен для очень высокого уровня тестирования (запросы и ответы). На самом деле это не должно заботить внутренние органы, то есть, какие службы или слушатели вызываются. Важно только, чтобы при вводе x (ваш запрос) вы получали вывод y (ваш ответ). Это позволяет гарантировать, что базовая функциональность c, воспринимаемая вашими пользователями, всегда соблюдается, не заботясь о том, как это делается. Делая эти тесты очень гибкими.
Рассматривая контейнер и сервисы, вы переходите на более низкий уровень тестирования, который тестирует взаимосвязанные сервисы. Обычно это делается только в том же процессе по причинам, которые вы уже выяснили. У теста более высокого уровня есть 2 отдельных жизненных цикла, один для самого теста и один для смоделированного веб-запроса к вашему приложению, следовательно, разные идентификаторы объектов.
Решение - либо передать что-то на более высокий уровень, например установив заголовки или изменив вывод, вы можете проверить тело ответа. Вы также можете записать в некоторый файл журнала и проверить журналы до / после запроса на это сообщение.
Другой вариант - переместить весь тест на более низкий уровень, где вам не нужны запросы, и вместо этого работать только с сервисами. Для этого вы можете использовать KernelTestCase
(вместо WebTestCase
) и вместо звонка createClient()
вы звоните bootKernel
. Это даст вам доступ к вашему контейнеру, где вы можете изменить EventDispatcher. Вместо отправки запроса вы можете либо напрямую вызвать код, например, отправить событие, если вы хотите только протестировать слушателей, либо вы можете сделать свой контроллер доступным в качестве службы, а затем вручную создать запрос, вызвать действие и затем либо проверить ответ или что-то еще, на что вы хотите заявить. Это может выглядеть примерно так:
public function testActionFiresEvent()
{
$kernel = static::bootKernel();
$eventDispatcher = $kernel->getContainer()->get('event_dispatcher');
// ...
$request = Request::create();
// This might not work when the controller
// You can create a service configuration only used by tests,
// e.g. "config/services_test.yaml" and provide the controller service there
$controller = $kernel->getContainer()->get(MyController::class);
$response = $controller->endpointAction($request);
// ...Do assertions...
}