#php #symfony #testing #phpunit #symfony-3.4
#php #symfony #тестирование #phpunit #symfony-3.4
Вопрос:
Я застрял на том, как правильно протестировать метод в сервисе Symfony, единственной целью которого является вызов других методов в других сервисах.
Попытка модульного тестирования метода, высмеивая каждую зависимость и относительные методы, которые он использует, на мой взгляд, просто делает тест бесполезным, поскольку то, что я тестирую, в некотором смысле, заключается в том, что другие сервисы вызываются правильно.
Кроме того, как я читал в различных источниках, я не должен издеваться над тем, чем я не владею, и в основном все такие методы используют хотя бы один ( EntityManager
, EncoderFactory
и т.д.)
Попытка функционального тестирования с загрузкой ядра, захватом сервиса и вызовом метода была кошмаром, и я застрял на утверждении, что электронные письма были отправлены, поскольку мне нужен клиент и ответ, чтобы получить все электронные письма, которые были отправлены из профилировщика.
Это пример таких методов, которые я должен протестировать:
public function postRequestCreatedActions(PrivacyRequest $request, $sendNotifications = true)
{
$this->customLogger->logRequest($request);
if ($sendNotifications) {
$this->customMailer->sendRequestCreated($request);
}
$this->em->flush();
}
Итак, мой вопрос таков: если есть способ правильно протестировать подобные методы (модульные или функциональные), как я должен его протестировать?
Если подобный метод не поддается тестированию и его необходимо изменить или полностью удалить, как вы посоветуете провести его рефакторинг, не засоряя вызывающий его контроллер (каждый из них вызывается контроллером)? Или перенос всей этой логики на контроллер — единственный способ?
Ответ №1:
Как я понимаю, вам нужно протестировать метод из вашего сервиса. Этот метод вызывает другие сервисы из внедренных зависимостей. Если это так, вам нужно создать экземпляр сервиса внутри test, используя, например, фиктивные зависимости или просто аргументы (используя prophecy с предсказаниями метода вызова):
public function testPostRequestCreatedActions(): void
{
$em = $this->prophesize(EntityManagerInterface::class);
$em->flush()->willReturn(true)->shouldBeCalled();
$request = $this->prophesize(PrivacyRequest::class);
$logger = $this->prophesize(LoggerInterface::class);
$logger->logRequest(Argument::any())->shouldBeCalled();
$mailer = $this->prophesize(MailerInterface::class);
$mailer->sendRequestCreated(Argument::any())->shouldNotBeCalled();
$service = new Service($em->reveal(), $logger->reveal(), $mailer->reveal()); // assuming your service dependencies are in constructor
$service->postRequestCreatedActions($request->reveal(), false);
}
P.S Это не пример копирования-вставки, просто уловите основную идею