"Cannot set session ID after the session has started." 正在测试表格

"Cannot set session ID after the session has started." while testing form

我正在为我的应用程序编写单元测试。我写了一个函数来登录不同的用户(以测试用户级别)和一个函数来生成有效或无效的表单数据(以测试我的表单处理)。

测试提交表单时抛出异常:

Uncaught PHP Exception LogicException: "Cannot set session ID after the session has started."

我正在使用 Symfony 2.6.4。我找不到有关此错误消息的任何有用信息。该测试在不久前运行良好。

class ControllerTest extends WebTestCase
{
    public $client = null;
    public $route = 'home/';

    /**
     * @var \Doctrine\ORM\EntityManager
     */
    public $em;

    public function setUp()
    {
        self::bootKernel();
        $this->client = static::createClient();

        $this->em = static::$kernel->getContainer()
            ->get('doctrine')
            ->getManager()
        ;
    }

    public function logIn($role = 'admin')
    {
        if ($role === 'admin') {
            $userId = 20;
        } elseif ($role === 'user') {
            $userId = 29;
        }
        $user = $this->em->getRepository('Acme\DemoBundle\Entity\User')->find($userId);

        $session = $this->client->getContainer()->get('session');

        $firewall = 'main';
        $token = new UsernamePasswordToken($user, $user->getPassword(), $firewall);
        $session->set('_security_'.$firewall, serialize($token));
        $session->save();

        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);
    }

    public function getFormData($valid = true)
    {
        //function to generate (in)valid formdata
    }

    public function getFormRequest($data, $url)
    {
        return $this->client->request(
            'POST',
            $url,
            $data,
            [],
            [
                'CONTENT_TYPE'          => 'application/json',
                'HTTP_X-Requested-With' => 'XMLHttpRequest',
            ]
        );
    }

    //works OK
    public function testNewScenario()
    {
        $url = $this->baseurl . 'new';
        $this->logIn('admin');

        $crawler = $this->client->request('GET', $url);
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET " . $url);
    }

    public function testValidNewScenario()
    {
        $this->logIn('admin');

        $validData = $this->getFormData(true);

        //this function throws the exception
        $this->getFormRequest($validData, $this->baseurl);

        $this->assertEquals(200, $this->client->getResponse()->getStatusCode(), "Unexpected HTTP status code for POST " . $this->baseurl);
    }

}

这是我的 config_test.yml 的相关部分:

framework:
    test: ~
    session:
        storage_id: session.storage.mock_file
    profiler:
        collect: false

怎么回事?

我不知道这是否仍然是 OP 的问题,因为这是一个旧的 post,但同样的问题让我 运行 在 3 小时的大部分时间内都在兜圈子想办法摆脱它。并且看到似乎根本没有任何解决方案。这是一个可能的。

问题存在于尝试创建完整登录的测试中。

当前的 symfony 文档声明它首选使用 basic_http authentication in your tests, but if, like me, you need to be testing access levels youll need to be following this 方法。

问题似乎是在我们尝试设置 cookieJar 时出现的。这(对我来说)总是会引发错误。

Cannot set session ID after the session has started

事实证明,解决方案相当简单。在检查当前会话 ID 的条件中包装 cookie 集代码。

if( !$this->session->getId() ) { 
      $this->cookie = new Cookie( $this->session->getName(), $this->session->getId() );
      $this->client->getCookieJar()->set( $this->cookie ); // <--- this is the problem line
}

还值得注意的是,调用 $this->session->invalidate() 并没有 解决问题。

我希望这对某人有所帮助并节省他们一些时间。

这对我影响了 Symfony2.1(没有机会升级),但我看到有人提到 2.6 在与 FOSFFacebookBundle 结合使用时获得它(我相信问题已解决)。