尝试在实现Sessions的控制器方法上运行基于控制器的单元测试时,我遇到了一个问题。
在这种情况下,这是控制器方法:
/**
* @Route("/api/logout")
*/
public function logoutAction()
{
$session = new Session();
$session->clear();
return $this->render('PassportApiBundle:Login:logout.html.twig');
}
功能测试:
public function testLogout()
{
$client = static::createClient();
$crawler = $client->request('GET', '/api/logout');
$this->assertTrue($client->getResponse()->isSuccessful());
}
产生的错误:
由于已经发送了标头,因此无法启动会话。 (500内部服务器错误)
我已经尝试将$this->app['session.test'] = true;
放入测试中,但仍然没有。有没有人尝试解决这样的问题来对使用会话的控制器进行单元测试?
答案 0 :(得分:13)
首先,您应该使用容器中的会话对象。所以你的行动看起来应该更像:
/**
* @Route("/api/logout")
*/
public function logoutAction()
{
$session = $this->get('session');
$session->clear();
return $this->render('PassportApiBundle:Login:logout.html.twig');
}
然后在您的测试中,您可以将服务注入“客户端容器”。所以:
public function testLogout()
{
$sessionMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session')
->setMethods(array('clear'))
->disableOriginalConstructor()
->getMock();
// example assertion:
$sessionMock->expects($this->once())
->method('clear');
$client = static::createClient();
$container = $client->getContainer();
$container->set('session', $sessionMock);
$crawler = $client->request('GET', '/api/logout');
$this->assertTrue($client->getResponse()->isSuccessful());
}
使用此代码,您可以使用会话服务完成所需的一切。但你必须要注意两件事:
编辑:
我添加了一个断言
答案 1 :(得分:7)
就我而言,设置
就足够了framework:
session:
storage_id: session.storage.mock_file
config_test.yml
中的。 YMMV,我对我实际做的事情没有那么多想法,但它对我有用。
答案 2 :(得分:2)
这里只是为了完成塞浦路斯的回应。
正如Sven解释并在查看symfony的文档http://symfony.com/doc/2.3/components/http_foundation/session_testing.html时, 你必须使用MockFileSessionStorage对象将模拟会话实例化为第一个构造函数参数。
您需要使用:
use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;
代码应该是:
$sessionMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')
->setMethods(array('clear'))
->disableOriginalConstructor()
->setConstructorArgs(array(new MockFileSessionStorage()))
->getMock();