繁体   English   中英

PHPUnit失败了Symfony2 Sessions

[英]PHPUnit failing with Symfony2 Sessions

尝试在实现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; 进入测试,但仍然没有去。 有没有人尝试解决这样的问题来对使用会话的控制器进行单元测试?

首先,您应该使用容器中的会话对象。 所以你的行动看起来应该更像:

/**
 * @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());
}

使用此代码,您可以使用会话服务完成所需的一切。 但你必须要注意两件事:

  • 这个模拟只能为一个请求设置(如果你想在下一个请求中使用它,你应该再次设置它)。 这是因为客户端重启内核并在每个请求之间重建容器。
  • Symfony 2.1中的会话处理与Symfony 2略有不同

编辑:

我添加了一个断言

在我的情况下,它足以设置

framework:
    session:
        storage_id: session.storage.mock_file

config_test.yml YMMV,我没有那么多想法,我实际上在做什么,但它对我有用。

这里只是为了完成塞浦路斯的回应。

正如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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM