Блог веб-разработчика v 1.0.0
Symfony2, AngularJS, React, Gulp, PhpStorm и много других страшных слов

Авторизация в тестах PHPUnit в Symfony2

10 лет назад
8464 просмотра
PHP Frameworks PHPUnit Symfony2

Способ из документации

Тестовый клиент можно настроить для авторизации по логину/паролю. Делается это вот так:

$client = static::createClient(array(), array(
    'PHP_AUTH_USER' => 'user',
    'PHP_AUTH_PW'   => 'userpass',
));

Способ не очень удобен, т.к. исходный текст теста должен содержать логин/пароль в открытом виде. Не слишком безопасно, да и не слишком удобно (а если пароль изменится?). Конечно, можно создать пользователей in_memory, прописанных прямо в конфиг-файле, но вам захочется использовать этот конфиг только для тестового окружения, а файл security.yml должен быть только один и, в общем, у вас будет куча проблем со всем этим.

Альтернативный способ

use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

class WebUserTestCase extends WebTestCase
{
    protected function logIn(Client $client, $email)
    {
        $user = $client->getContainer()->get('fos_user.user_manager')->findUserByEmail($email);

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

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

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

Это готовый класс от которого можно наследовать свои функциональные тесты.

Авторизация производится вызовом logIn($client, '[email protected]'). Само собой, пользователь с таким Email должен существовать, однако пароль мы не указываем, что избавляет нас от многих неудобств. Метод использует FOSUserBundle для получения пользователя и его ролей, так что придется переписать пару строчек, если у вас этот бандл не используется.

Что еще почитать