Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/238.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony功能测试-如何使用请求模拟控制器注入服务(提交)_Php_Unit Testing_Symfony - Fatal编程技术网

Php Symfony功能测试-如何使用请求模拟控制器注入服务(提交)

Php Symfony功能测试-如何使用请求模拟控制器注入服务(提交),php,unit-testing,symfony,Php,Unit Testing,Symfony,我如何在功能测试用例中模拟一个正在进行“请求”(表单/提交)的服务。在我发出请求之后,我对容器所做的所有更改和模拟都将丢失 我正在使用Symfony 4或5。此处发布的代码也可以在此处找到: 我有以下情况: SomeActions服务被注入控制器构造函数 在功能单元测试中,我尝试模拟SomeActions函数,以检查它们是否执行(它发送电子邮件或类似的东西) 我模拟服务并在单元测试中覆盖它: $container->set('App\Model\SomeActions', $someA

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

我正在使用Symfony 4或5。此处发布的代码也可以在此处找到:

我有以下情况:

  • SomeActions服务被注入控制器构造函数
  • 在功能单元测试中,我尝试模拟SomeActions函数,以检查它们是否执行(它发送电子邮件或类似的东西)
我模拟服务并在单元测试中覆盖它:

$container->set('App\Model\SomeActions', $someActions);
现在在测试中,我做了一个$client->submit($form)我知道它会终止内核

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

下面是我添加到symfony演示应用程序的示例代码

服务业。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\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();
...

这个答案对你有帮助吗?(注意最后一句话)不是真的,它的解决方案是什么?这只是我的猜测-但您可能需要注入模拟服务两次(在获取页面之前和提交表单之前)。
$client->disableReboot()$客户->提交($form)如果我这样做,那么我就实现了我想要的。不确定这是否是最好的方法。此外,在
static::createClient()
之前对容器所做的更改似乎丢失了,因此模拟必须在客户端创建之后进行。
public function testSomeAction()
{
    $client = static::createClient();
    $client->disableReboot();
...