【问题标题】:Test mocked service in controller in symfony 4.4在 symfony 4.4 的控制器中测试模拟服务
【发布时间】:2021-12-23 02:49:36
【问题描述】:

我想在我的 symfony 4.4 项目中测试这个控制器:

final class WebhookController extends AbstractController
{
    private CustomLoggerService $customLogger;
    private EntityManagerInterface $entityManager;
    private MyService $myService;
    private UserMailer $userMailer;
    private AdminMailer $adminMailer;

    public function __construct
    (
        CustomLoggerService $customLogger,
        EntityManagerInterface $entityManager,
        MyService $myService,
        UserMailer $userMailer,
        AdminMailer $adminMailer
    )
    {
        $this->customLogger = $customLogger;
        $this->myService = $myService;
        $this->userMailer = $userMailer;
        $this->adminMailer = $adminMailer;
        $this->entityManager = $entityManager;
    }

    /**
     * @Route("/webhook/new", name="webhook_new")
     * @param Request $request
     * @return Response
     */
    public function new(Request $request)
    {
        $uri = $request->getUri();
        $this->customLogger->info("new event uri ".$uri);
        $query = $request->query->all();
        if(isset($query['RessourceId']))
        {
            //infos
            $id = $query['RessourceId'];
            $event = $this->myService->getInfos($id);
            $infoId = $event->infoId;
            $this->customLogger->info("new info id ".$infoId);

            $userRepo = $this->entityManager->getRepository(User::class);
            $user = $userRepo->findOneByEventUserId((int)$event->owners[0]);

            //mail sent
            $this->userMailer->sendAdminEvent($event, $user);
            $this->customLogger->info("new mail sent");

        }
        else
        {
            $this->adminMailer->sendSimpleMessageToAdmin("no ressource id", "no ressource id");
        }
        return new JsonResponse();
    }
}

我需要模拟 MyService,因为它调用外部 API

这是我的测试:

class WebhookControllerTest extends WebTestCase
{
    use LoginTrait;

    public function testNewPayinIRessourceIdExists()
    {
        self::ensureKernelShutdown();
        /** @var KernelBrowser $client */
        $client = $this->startClient();
        $client->enableProfiler();

        $myService = $this->createMock(MyService::class);
        $myService->expects($this->once())->method("getInfos")->willReturn([
            [
                'hi'=>'hi'
            ]
        ]);


        // if I do this, I can't inject my mocked service
        $client->request('GET', '/webhook/new/?RessourceId=1111');
        
       // if I do this, I can't autowire all my dependencies of my controller
       $controller = new WebhookController(xxxx);
       $controller->new(xxx);
    }
}

测试我的控制器的最佳方法是什么?如果我这样做 new WebhookController(xxxx) 我有很多依赖项需要其他依赖项并且它是不可维护的。 或者我应该移动自定义日志并在其他服务中发送电子邮件并保持控制器没有这些依赖关系?

【问题讨论】:

    标签: php symfony testing mocking symfony4


    【解决方案1】:

    你不需要自己实例化控制器。

    您可以将需要模拟的服务公开用于测试环境,在容器中创建模拟和覆盖。

    1. config/services_test.yaml添加以下配置

      App\Service\MyService:
        public: true
      
    2. 模拟服务

      $myService = $this->createMock(MyService::class);
      $myService->expects($this->once())->method("getInfos")->willReturn([
          [
              'hi'=>'hi'
          ]
      ]);
      self::$container->set(MyService::class, $myService);
      
    3. 并发出 HTTP 请求

      $client->request('GET', '/webhook/new/?RessourceId=1111');
      

    【讨论】:

    • 谢谢@greeflas 我不知道这个:) 我试过了,但我不能做我想做的事。当我使用这种技术时,$myService->getInfos(1111) 在我的测试中返回我的正确对象,但在测试中,我测试的控制器仍然想要使用 API 并尝试连接它并使用真实方法而不是我的模拟。似乎模拟没有传递给控制器​​。你明白为什么吗?非常感谢:)
    • 我改的,不知道加参数是不是问题services: App\Service\MyService: arguments: $myParameters: '%my_parameters%' public: true
    • 你能试试static::$kernel->getContainer()->set(MyService::class, $myService)吗?它应该与控制器内部的容器相同。
    • 我试过 $client->getContainer()->set(MyService::class, $myService);self::$container->set(MyService::class, $myService);static::$kernel->getContainer()->set(MyService::class, $myService) 他们都没有工作:/
    • 哇非常感谢!!!你的例子在我的环境中工作所以......我不知道为什么我有这个问题。我会继续我的调查谢谢:)
    猜你喜欢
    • 2018-04-15
    • 2020-09-03
    • 2014-11-22
    • 2016-08-18
    • 2014-01-16
    • 2019-04-13
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多