Как зарегистрировать пользователя в сеансе в функциональном тесте в Symfony 2.3?

Я прочитал много сообщений о stackoverflow об этом. Но большинство методов, не полезных в Symfony 2.3. Поэтому я попытался вручную войти в систему вручную, чтобы сделать некоторые действия в фоновом режиме. Вот мой security.yml

security: ... role_hierarchy: ROLE_SILVER: [ROLE_BRONZE] ROLE_GOLD: [ROLE_BRONZE, ROLE_SILVER] ROLE_PLATINUM: [ROLE_BRONZE, ROLE_SILVER, ROLE_GOLD] ROLE_ADMIN: [ROLE_BRONZE, ROLE_SILVER, ROLE_GOLD, ROLE_PLATINUM, ROLE_ALLOWED_TO_SWITCH] providers: database: entity: { class: Fox\PersonBundle\Entity\Person, property: username } firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false login: pattern: ^/person/login$ security: false main: pattern: ^/ provider: database form_login: check_path: /person/login-check login_path: /person/login default_target_path: /person/view always_use_default_target_path: true logout: path: /person/logout target: / anonymous: true access_control: - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/person/registration, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/person, roles: ROLE_BRONZE } 

Вот мой тест:

 class ProfileControllerTest extends WebTestCase { public function setUp() { $kernel = self::getKernelClass(); self::$kernel = new $kernel('dev', true); self::$kernel->boot(); } public function testView() { $client = static::createClient(); $person = self::$kernel->getContainer()->get('doctrine')->getRepository('FoxPersonBundle:Person')->findOneByUsername('master'); $token = new UsernamePasswordToken($person, $person->getPassword(), 'main', $person->getRoles()); self::$kernel->getContainer()->get('security.context')->setToken($token); self::$kernel->getContainer()->get('event_dispatcher')->dispatch( AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($token)); $crawler = $client->request('GET', '/person/view'); } 

И когда я запускаю этот тест, $person = $this->get(security.context)->getToken()->getUser(); метод не работает в тестовом контроллере. Скажем, если в контроллере вызов $person->getId(); У меня будет ошибка. Call to a member function getId() on a non-object in...

Итак, можете ли вы правильно указать способ входа пользователя в функциональный тест в Symfony 2.3?

Благодаря!

EDIT_1 : Если я изменю Symfony/Component/Security/Http/Firewall/ContextListener.php и прокомментирую одну строку:

 if (null === $session || null === $token = $session->get('_security_'.$this->contextKey)) { // $this->context->setToken(null); return; } 

все тесты продолжаются без ошибок.

EDIT_2 : Это ссылка, которую я пытаюсь использовать: первая вторая третья четвертая пятая шестая седьмая восьмая девятая

Related of "Как зарегистрировать пользователя в сеансе в функциональном тесте в Symfony 2.3?"

Окончательно я решаю это! Это пример рабочего кода:

 use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\BrowserKit\Cookie; class ProfileControllerTest extends WebTestCase { protected function createAuthorizedClient() { $client = static::createClient(); $container = static::$kernel->getContainer(); $session = $container->get('session'); $person = self::$kernel->getContainer()->get('doctrine')->getRepository('FoxPersonBundle:Person')->findOneByUsername('master'); $token = new UsernamePasswordToken($person, null, 'main', $person->getRoles()); $session->set('_security_main', serialize($token)); $session->save(); $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId())); return $client; } public function testView() { $client = $this->createAuthorizedClient(); $crawler = $client->request('GET', '/person/view'); $this->assertEquals( 200, $client->getResponse()->getStatusCode() ); } 

Надеюсь, это поможет сэкономить ваше время и нервы;)

В качестве дополнения к принятому решению я покажу свою функцию входа пользователя в контроллер .

 // <!-- Symfony 2.4 --> // use Symfony\Component\Security\Core\AuthenticationEvents; use Symfony\Component\Security\Core\Event\AuthenticationEvent; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; private function loginUser(UsernamePasswordToken $token, Request $request) { $this->get('security.context')->setToken($token); $s = $this->get('session'); $s->set('_security_main', serialize($token)); // `main` is firewall name $s->save(); $ed = $this->get('event_dispatcher'); $ed->dispatch( AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($token) ); $ed->dispatch( "security.interactive_login", new InteractiveLoginEvent($request, $token) ); } - // <!-- Symfony 2.4 --> // use Symfony\Component\Security\Core\AuthenticationEvents; use Symfony\Component\Security\Core\Event\AuthenticationEvent; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; private function loginUser(UsernamePasswordToken $token, Request $request) { $this->get('security.context')->setToken($token); $s = $this->get('session'); $s->set('_security_main', serialize($token)); // `main` is firewall name $s->save(); $ed = $this->get('event_dispatcher'); $ed->dispatch( AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($token) ); $ed->dispatch( "security.interactive_login", new InteractiveLoginEvent($request, $token) ); } - // <!-- Symfony 2.4 --> // use Symfony\Component\Security\Core\AuthenticationEvents; use Symfony\Component\Security\Core\Event\AuthenticationEvent; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; private function loginUser(UsernamePasswordToken $token, Request $request) { $this->get('security.context')->setToken($token); $s = $this->get('session'); $s->set('_security_main', serialize($token)); // `main` is firewall name $s->save(); $ed = $this->get('event_dispatcher'); $ed->dispatch( AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($token) ); $ed->dispatch( "security.interactive_login", new InteractiveLoginEvent($request, $token) ); }