Symfony2-为作为参数传递对象的控制器编写测试的问题
我在为Symonfy2捆绑包中的控制器编写测试时遇到了一个问题 该控制器只能通过Twig的Symfony2-为作为参数传递对象的控制器编写测试的问题,symfony,phpunit,twig,Symfony,Phpunit,Twig,我在为Symonfy2捆绑包中的控制器编写测试时遇到了一个问题 该控制器只能通过Twig的{%render%}访问,并且在应用程序中运行良好,但无论我以何种方式进行测试,测试都会失败。下面是基本情况: 控制器A-“父”控制器。通过典型的URL加载 控制器B。通过{%render%}从控制器a呈现的模板加载。对象变量被传递到{%render%}标记中的控制器B 控制器C。通过{%render%}从控制器B呈现的模板加载 这一切在实际应用程序中都非常有效,以这种方式进行结构设计可以最大限度地实现代码
{%render%}
访问,并且在应用程序中运行良好,但无论我以何种方式进行测试,测试都会失败。下面是基本情况:
控制器A
-“父”控制器。通过典型的URL加载
控制器B
。通过{%render%}
从控制器a
呈现的模板加载。对象变量被传递到{%render%}
标记中的控制器B
控制器C
。通过{%render%}
从控制器B
呈现的模板加载
这一切在实际应用程序中都非常有效,以这种方式进行结构设计可以最大限度地实现代码重用。当我开始为ControllerB
编写单元测试时,出现了这个问题。因为这是一个仅限内部的控制器,所以我认为最好调用以下测试方法:
$this->obj=newcontrollerb();
$this->obj->setContainer($this->getContainer());
$this->obj->methodToTest();
但这让我看到了这个错误信息:
Twig_Error_Runtime:在第XX行呈现模板(“您无法创建非活动范围(“请求”)的服务(“请求”)时引发异常-这是我们试图通过{%render%}从控制器C呈现方法的那一行
因此,似乎因为对ControllerB
中的方法的调用不是请求的一部分,所以它不能向ControllerC
发出内部子请求。解决方案似乎是通过以下方式向控制器B
发出请求:
$this->client=static::createClient(…);
$crawler=$this->client->request('GET','/routeToControllerB');
但这也不行,因为我需要将对象和数组传递给ControllerB
中的方法,它们太大,无法序列化/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