gpt4 book ai didi

php - Symfony 功能测试 - 如何使用请求模拟 Controller 注入(inject)的服务(提交)

转载 作者:行者123 更新时间:2023-12-04 12:10:33 25 4
gpt4 key购买 nike

如何在发出“请求”(表单/提交)的功能测试用例中模拟服务。发出请求后,我对容器所做的所有更改和模拟都丢失了。

我使用的是 Symfony 4 或 5。这里发布的代码也可以在这里找到:https://github.com/klodoma/symfony-demo

我有以下场景:

  • 一些行动 服务被注入(inject) Controller 构造函数
  • 在功能单元测试中,我尝试模拟 一些行动 函数以检查它们是否被执行(它发送电子邮件或类似的东西)

  • 我模拟服务并在单元测试中覆盖它:
    $container->set('App\Model\SomeActions', $someActions);

    现在在测试中我做了一个 $client->submit($form); 我知道它终止了内核。

    我的问题是:如何注入(inject)我的模拟 $someActions $client->submit($form); 之后的容器中

    下面是我添加到 symfony 演示应用程序的示例代码
    https://github.com/symfony/demo

    enter image description here

    在 services.yaml
    App\Model\SomeActions:
    public: true

    SomeController.php
    <?php

    namespace App\Controller;

    use App\Model\SomeActions;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Annotation\Route;

    /**
    * Controller used to send some emails
    *
    * @Route("/some")
    */
    class SomeController extends AbstractController
    {
    private $someActions;

    public function __construct(SomeActions $someActions)
    {
    //just dump the injected class name
    var_dump(get_class($someActions));

    $this->someActions = $someActions;
    }

    /**
    * @Route("/action", methods="GET|POST", name="some_action")
    * @param Request $request
    * @return Response
    */
    public function someAction(Request $request): Response
    {

    $this->someActions->doSomething();

    if ($request->get('send')) {
    $this->someActions->sendEmail();
    }

    return $this->render('default/someAction.html.twig', [
    ]);
    }
    }

    一些行动
    <?php

    namespace App\Model;

    use Symfony\Component\Mailer\MailerInterface;
    use Symfony\Component\Mime\Email;

    class SomeActions
    {
    private $mailer;

    public function __construct(MailerInterface $mailer)
    {
    $this->mailer = $mailer;
    }

    public function doSomething()
    {
    echo 'doSomething';
    }

    public function sendEmail()
    {
    echo 'sendEmail';

    $email = (new Email())
    ->from('hello@example.com')
    ->to('you@example.com')
    ->subject('Time for Symfony Mailer!')
    ->text('Sending emails is fun again!')
    ->html('<p>See Twig integration for better HTML integration!</p>');
    $this->mailer->send($email);
    }

    }

    SomeControllerTest.php
    <?php

    namespace App\Tests\Controller;

    use App\Model\SomeActions;
    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

    class SomeControllerTest extends WebTestCase
    {
    public function testSomeAction()
    {
    $client = static::createClient();

    // gets the special container that allows fetching private services
    $container = self::$container;


    $someActions = $this->getMockBuilder(SomeActions::class)
    ->disableOriginalConstructor()
    ->getMock();

    //expect that sendEmail will be called
    $someActions->expects($this->once())
    ->method('sendEmail');

    //overwrite the default service: class: Mock_SomeActions_e68f817a
    $container->set('App\Model\SomeActions', $someActions);


    $crawler = $client->request('GET', '/en/some/action');

    //submit the form
    $form = $crawler->selectButton('submit')->form();

    $client->submit($form);

    //after submit the default class injected in the controller is "App\Model\SomeActions" and not the mocked service
    $response = $client->getResponse();

    $this->assertResponseIsSuccessful($response);

    }
    }

    最佳答案

    解决方法是禁用内核重启:

    $client->disableReboot();

    如果人们深入挖掘以了解引擎盖下发生的事情,这是有道理的。
    我仍然不确定是否有更直接的答案。
    public function testSomeAction()
    {
    $client = static::createClient();
    $client->disableReboot();
    ...

    关于php - Symfony 功能测试 - 如何使用请求模拟 Controller 注入(inject)的服务(提交),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60491748/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com