Вот моя проблема, я добавляю переменную сеанса из функционального тестового контроллера, и они не выходят за действие, нацеленное на тестирование.
Я сделал метод входа в систему и использовал совет по кулинарной книге для входа в систему. Я немного настроил его, чтобы разрешить использование двух учетных записей: admin и superadmin
/** * @param $account string the account to log in with (authorized : superadmin and admin) */ protected function logIn($account) { $this->session = $this->container->get('session'); // Cookbook try // $this->session = new Session(new MockFileSessionStorage()); $user = $this->em->getRepository('LCHUserBundle:User')->findOneByUsername($account); $firewall = 'admin_area'; switch($account) { case self::SUPER_ADMIN_LOGIN: $token = new UsernamePasswordToken($user, $account, $firewall, array('ROLE_SUPER_ADMIN')); $this->client->setServerParameter("SERVER_NAME", SiteControllerTest::ROOT_SITE); $this->client->setServerParameter("HTTP_HOST", SiteControllerTest::ROOT_SITE); break; case self::ADMIN_LOGIN: $token = new UsernamePasswordToken($user, $account, $firewall, array('ROLE_ADMIN')); // Session var I wish to have on my controller action tested $this->session->set('currentSite', $this->em->getRepository('LCHMultisiteBundle:Site')->find(1)); $this->session->save(); // Use to force server canonical name for admin test $this->client->setServerParameter("SERVER_NAME", SiteControllerTest::ROOT_SITE); $this->client->setServerParameter("HTTP_HOST", SiteControllerTest::TEST_SITE); break; default: throw new UsernameNotFoundException('Username provided doesn\'t match any authorized account'); } // Save user in session $this->session->set('_security_'.$firewall, serialize($token)); $this->session->set('user', $user); $this->session->save(); // $this->container->set('session', $this->session); $cookie = new Cookie($this->session->getName(), $this->session->getId()); $this->client->getCookieJar()->set($cookie);
Мой метод setUp () делает следующее:
/** * {@inheritDoc} */ protected function setUp() { // Initiates client $this->client = static::createClient(); $this->container = $this->client->getContainer(); $this->application = new Application($this->client->getKernel()); $this->application->setAutoExit(false); $this->translator = $this->container->get('translator'); $this->em = $this->container ->get('doctrine') ->getManager(); }
Вы можете видеть, что я установил сеанс vars для аутентификации. Они отображаются правильно, когда я отбрасываю сеанс var из проверенного действия, но если я добавлю свой текущий сеанс var, он, похоже, не сохраняется. Поскольку я использую тестовый контейнер, предоставленный клиентом, он должен быть передан, не так ли?
PS: Я также переопределил класс Client, согласно этому другому вопросу .
Я нашел множество сообщений по теме, но ни один из них не дает никакого рабочего решения ( этого , этого или этого ). Я также нашел эту статью поваренной книги .
ОБНОВЛЕНИЕ: спасибо замечанию Алекс Блекс, я уточняю здесь некоторые части моего вопроса.
Не совсем понятно, что вы тестируете, какие ваши ожидания и где это не удается. Было бы целесообразно добавить фактический тест. Зачем вам нужен контейнер, переводчик и т. Д. В ваших тестах?
Для сеансов ничего особенного не требуется. Рассмотрим этот пример контроллера, который сохраняет значение «test» в сеансе и увеличивает его на последовательные вызовы:
/** * @Route("/session") * @Method({"GET"}) */ public function session() { $session = $this->container->get('session'); $current = $session->get('test', 0); $session->set('test', $current + 1); return new Response($current); }
И этот тест проходит:
/** * @test */ public function session_increments() { $client = static::createClient(); $client->request("GET", '/session'); $this->assertEquals('0', $client->getResponse()->getContent()); $client->request("GET", '/session'); $this->assertEquals('1', $client->getResponse()->getContent()); }
Логика вашего приложения может быть более сложной, но тест должен оставаться практически тем же самым – первый вызов для входа в систему, второй вызов для подтверждения ответа содержит что-то уникальное для вошедшего в систему пользователя.
ОБНОВИТЬ
Следует избегать игры с внутренней реализацией в функциональных тестах, насколько это возможно, но может быть важно для некоторых краевых случаев, например, для упрощения сценариев тестирования.
В следующем примере тестируется один и тот же контроллер, устанавливая определенное значение для переменной сеанса из тестового сценария и проверяя, что значение возвращается приложением:
/** * @test */ public function session_returns_value() { $client = static::createClient(); $session = $client->getContainer()->get('session'); $session->set('test', 12); $client->request("GET", '/session'); $this->assertEquals('12', $client->getResponse()->getContent()); }