«Невозможно установить идентификатор сеанса после начала сеанса». Во время тестирования формы

4

Я пишу модульные тесты для своего приложения. Я написал функцию для входа в систему другого пользователя (для проверки уровней пользователей) и функции для генерации действительных или недопустимых данных формы (для проверки обработки моей формы).

Когда тест отправляет форму, он выдает исключение:

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

Что происходит?

  • 0
    Я не уверен, но похоже, что вам нужно выйти перед тем, как войти в систему как пользователь.
  • 0
    вероятно, идентификатор пользователя, который вы ищете, изменился?
Показать ещё 5 комментариев
Теги:
unit-testing
phpunit

1 ответ

1
Лучший ответ

Я не знаю, является ли это проблемой для OP, поскольку это старый пост, но та же проблема заставила меня бегать по кругу в течение 3 часов, пытаясь найти выход из нее. И, видя, что там нигде не существует никакого решения. Это возможно.

Проблема существует в тестах, которые пытаются создать полный логин.

В текущем Symfony docs указано, что он предпочитает использовать basic_http аутентификацию в ваших тестах, но если, как и я, вам необходимо тестировать уровни доступа вы должны следовать этот метод.

Проблема возникает, когда мы пытаемся установить cookieJar. Это (для меня) всегда выдавало ошибку.

Невозможно установить идентификатор сеанса после запуска сеанса

решение, как оказалось, достаточно просто. Оберните код установленного файла 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, получая его в сочетании с FOSFacebookBundle (где я считаю, что проблема была исправлена).

  • 0
    Это не работает в Symfony 2.7, это не будет работать, то есть: пользователь не будет авторизован.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню