我在为 Symonfy2 包中的控制器编写测试时遇到了问题。
控制器只能通过 Twig's 访问{% render %}
,并且在应用程序中运行良好,但无论我采用哪种方式,测试都会失败。这基本上是发生了什么:
控制器A
。- “父”控制器。通过典型的 URL 加载。
控制器B
。{% render %}
通过从 Controller 呈现的模板加载A
。B
一个对象变量在{% render %}
标签 中被传递给 Controller 。
控制器C
。{% render %}
通过从 Controller 呈现的模板加载B
。
这一切在实际应用程序中都非常有效,并且以这种方式构造事物可以最大程度地重用代码。当我开始为 Controller 编写单元测试时,问题就出现了B
。因为这是一个内部唯一的控制器,我认为最好这样调用测试方法:
$this->obj = new ControllerB();
$this->obj->setContainer($this->getContainer());
$this->obj->methodToTest();
但这导致我收到此错误消息:
Twig_Error_Runtime:在第 XX 行渲染模板(“您无法创建非活动范围(“请求”)的服务(“请求”)。”)期间引发异常 -这是我们尝试的行通过 {% render %} 从 Controller C 渲染一个方法
因此,似乎因为对 ControllerB
中方法的调用不是请求的一部分,所以它不能向 controller 发出内部子请求C
。对此的解决方案似乎是B
通过以下方式向控制器发出请求:
$this->client = static::createClient(...);
$crawler = $this->client->request('GET', '/routeToControllerB');
但这也行不通,因为我需要将对象和数组传递给 Controller 中的方法B
,而且它们太大而无法serialize/json_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 = new UsernamePasswordToken($user, 'phpunit', 'PHPSESSID', $user->getRoles());
$container->get('security.context')->setToken($token);
$this->obj = new ControllerB();
$this->obj->setContainer($container);
但是到目前为止,我找不到任何可以让我测试需要传递对象并{% render %}
在模板中使用(内部子请求)的控制器方法的东西。以前有人遇到过这个吗?