I'm running into an issue when trying to run a controller based unit test on a controller method that implements Sessions.
In this case, here is the controller method:
/**
 * @Route("/api/logout")
 */
public function logoutAction()
{
    $session = new Session();
    $session->clear();
    return $this->render('PassportApiBundle:Login:logout.html.twig');
}
And the functional test:
public function testLogout()
{
    $client = static::createClient();
    $crawler = $client->request('GET', '/api/logout');
    $this->assertTrue($client->getResponse()->isSuccessful());
}
The error that is produced:
Failed to start the session because headers have already been sent. (500 Internal Server Error)
I've tried placing in $this->app['session.test'] = true; into the test, but still no go. Has anyone tried resolving an issue like this to unit testing a controller that uses a session?
First of all you should use session object from container. So your action should look more like:
/**
 * @Route("/api/logout")
 */
public function logoutAction()
{
    $session = $this->get('session');
    $session->clear();
    return $this->render('PassportApiBundle:Login:logout.html.twig');
}
And then in your test you can inject service into "client's container". So:
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());
}
With this code you can do everything you want with your session service. But You have to be aware two things:
edit:
I've added an assertion
In my case, it was enough to set
framework:
    session:
        storage_id: session.storage.mock_file
in the config_test.yml. YMMV, and I don't have that much of an idea what I'm actually doing, but it works for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With