Symfony 2 SessionCsrfProvider& PHPUnit测试

时间:2013-05-10 15:04:38

标签: symfony phpunit

修改

我自己回答了这个问题,很简单:

$session = $this->getMock(
  '\Symfony\Component\HttpFoundation\Session\Session',
  array(),
  array(),
  '',
  false // don't call constructor
);
$container->register('session', $session);

在phpunit bootstrap文件中模拟会话对象。

+++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++

在我看来,无法正确测试这一点。

我正在使用Symfony 2独立组件 - 不使用FrameworkBundle等。我有一个控制器,它又创建一个表单,然后(尝试)将Csrf扩展添加到表单构建器。

但是,传入会话对象只会给我:

RuntimeException: Failed to start the session because headers have already been sent.

产生此代码的一些代码:

$session = $this->container->get('session') // instance of Symfony\Component\HttpFoundation\Session\Session
$form_obj = new MyForm(); // extends AbstractType
$secret   = $form_obj->getName(); // something random
$form_obj->addExtension(new CsrfExtension(new SessionCsrfProvider($session, $secret)));

好的,因此会话无法启动,因为PHPUnit首先发送输出。把     在session_start();

位于bootstrap文件的顶部,无法提供帮助或工作。

RuntimeException: Failed to start the session because a session has already been started

并且在任何情况下,这都是一个软糖修复因为你不会在两个不同的地方开始一个会话。

接下来,我尝试按照这些说明注册模拟会话对象:http://symfony.com/doc/master/components/http_foundation/session_testing.html

但遗憾的是,SessionCsrfProvider接口需要:

Argument 1 passed to 
Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider::__construct() 
must be an instance of Symfony\Component\HttpFoundation\Session\Session, 
instance of 
Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage given

所以......我实际上无法在任何测试代码中使用SessionCsrfProvider,除非我将会话作为PHPUnit模拟提供给它...但是那时需要我改变代码的设计以注入会话对象作为一个调用addExtension()方法的方法的构造函数或参数。目前,上面添加扩展名的代码包含在函数本身中,因此这意味着需要手动传递会话对象,我真的不想介绍。

任何想法?

1 个答案:

答案 0 :(得分:0)

我知道我有点迟到了,但另一种更好的方法是使用Symfonys MockArraySessionStorage。

$session = new Session(new MockArraySessionStorage());

$csrfProvider = new SessionCsrfProvider($session, $secret);