如何正确测试使用其他服务的服务方法

时间:2019-03-26 17:11:58

标签: php symfony testing phpunit symfony-3.4

我坚持如何正确测试Symfony服务上的方法,其唯一目的是在其他服务上调用其他方法。

在我看来,尝试通过模拟每个依赖项及其所使用的相对方法来对方法进行单元测试只会使测试无用,因为在某种程度上,我正在测试的是其他服务的调用正确。
而且,正如我在各种资料中所读到的那样,我不应该嘲笑自己不拥有的东西,基本上所有这些方法都至少使用一种(EntityManagerEncoderFactory等)

尝试通过引导内核,获取服务并调用该方法进行功能测试是一场噩梦,而我一直坚持断定电子邮件已发送,因为我需要一个客户端和一个响应来获取所有电子邮件。是从探查器发送的。

这是我必须测试的此类方法的示例:

public function postRequestCreatedActions(PrivacyRequest $request, $sendNotifications = true)
{
    $this->customLogger->logRequest($request);
    if ($sendNotifications) {
        $this->customMailer->sendRequestCreated($request);
    }
    $this->em->flush();
}

所以,我的问题是:如果有一种方法可以正确测试这种方法(单元或功能),我应该如何进行测试?
如果像这样的方法是不可测试的,并且需要更改或完全删除,那么您如何建议重构它而不阻塞调用它的控制器(每个方法都由控制器调用)?还是将所有这些逻辑移至控制器的唯一方法?

1 个答案:

答案 0 :(得分:0)

据我了解,您必须从服务中测试方法。此方法从注入的依赖项调用另一个服务。如果是这样,您必须使用模拟的依赖项或仅使用参数实例化测试内的服务(例如,将预言与调用方法的预测结合使用):

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这不是一个复制粘贴示例,只是获得主要思想