Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.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
Symfony2-为作为参数传递对象的控制器编写测试的问题_Symfony_Phpunit_Twig - Fatal编程技术网

Symfony2-为作为参数传递对象的控制器编写测试的问题

Symfony2-为作为参数传递对象的控制器编写测试的问题,symfony,phpunit,twig,Symfony,Phpunit,Twig,我在为Symonfy2捆绑包中的控制器编写测试时遇到了一个问题 该控制器只能通过Twig的{%render%}访问,并且在应用程序中运行良好,但无论我以何种方式进行测试,测试都会失败。下面是基本情况: 控制器A-“父”控制器。通过典型的URL加载 控制器B。通过{%render%}从控制器a呈现的模板加载。对象变量被传递到{%render%}标记中的控制器B 控制器C。通过{%render%}从控制器B呈现的模板加载 这一切在实际应用程序中都非常有效,以这种方式进行结构设计可以最大限度地实现代码

我在为Symonfy2捆绑包中的控制器编写测试时遇到了一个问题

该控制器只能通过Twig的
{%render%}
访问,并且在应用程序中运行良好,但无论我以何种方式进行测试,测试都会失败。下面是基本情况:

控制器
A
-“父”控制器。通过典型的URL加载

控制器
B
。通过
{%render%}
从控制器
a
呈现的模板加载。对象变量被传递到
{%render%}
标记中的控制器
B

控制器
C
。通过
{%render%}
从控制器
B
呈现的模板加载

这一切在实际应用程序中都非常有效,以这种方式进行结构设计可以最大限度地实现代码重用。当我开始为Controller
B
编写单元测试时,出现了这个问题。因为这是一个仅限内部的控制器,所以我认为最好调用以下测试方法:

$this->obj=newcontrollerb();
$this->obj->setContainer($this->getContainer());
$this->obj->methodToTest();
但这让我看到了这个错误信息:

Twig_Error_Runtime:在第XX行呈现模板(“您无法创建非活动范围(“请求”)的服务(“请求”)时引发异常-这是我们试图通过{%render%}从控制器C呈现方法的那一行

因此,似乎因为对Controller
B
中的方法的调用不是请求的一部分,所以它不能向Controller
C
发出内部子请求。解决方案似乎是通过以下方式向控制器
B
发出请求:

$this->client=static::createClient(…);
$crawler=$this->client->request('GET','/routeToControllerB');
但这也不行,因为我需要将对象和数组传递给Controller
B
中的方法,它们太大,无法
序列化/json\u encode
并适合请求的URL

我尝试将请求强制放入对象容器:

$this->client=static::createClient();
$this->client->followRedirects();
$container=$this->getContainer();
$container->get('session')->start();
$request=request::createFromGlobals();
$container->set('request',$request);
$user=new\user(1111);
\Auth::set_user($user);
$user=new\Company\Component\Security\user\user(\Auth::user());
$token=newusernamepasswordtoken($user,'phpunit','PHPSESSID',$user->getRoles());
$container->get('security.context')->setToken($token);
$this->obj=newcontrollerb();
$this->obj->setContainer($container);

但到目前为止,我找不到任何东西可以让我测试一个控制器方法,该方法需要传递一个对象,并且在模板中使用
{%render%}
(一个内部子请求)。以前有人遇到过这种情况吗?

我知道我有点担心,但我的建议如下:

如果你真的想这样做,你可以让你的控制器成为一个服务,给它所有需要的依赖,然后写一个单元测试。看

但是我建议你不要对你的控制器进行单元测试。如果它们写得很好,就不包含任何业务逻辑,对它们进行单元测试是毫无意义的。 如果存在关联的路由,则应直接进行控制器的功能测试(但在这种情况下,您将无法直接为其提供对象),否则,如果控制器未设计为直接从浏览器访问(因为您为其提供了对象,或仅仅因为您不想访问),只需测试控制器,包括它,它将涵盖两个控制器。在您的示例中,只需测试控制器A,它就隐式地覆盖了B和C