Токен пользователя в функциональных тестах Symfony2

Я делаю функциональные тесты контроллеров Symfony2, наследуя свои тестовые классы от этого:

class InsecureWebTestCase extends WebTestCase {

    protected $client = null;

    public function setUp() {
        $this->client = static::createClient();
        $session = $this->client->getContainer()->get('session');
        $firewall = 'default';
        $token = new UsernamePasswordToken('[email protected]', null, $firewall, array('ROLE_USER', 'ROLE_ADMIN'));
        // $this->client->getContainer()->get('security.context')->setToken($token);
        $session->set("_security_$firewall", serialize($token));
        $session->save();
        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);
    }

}

Если я использую контроллер как часть приложения: $this->container->get('security.token_storage')->getToken()->getUser() и $this->getUser() являются экземплярами моего объекта Doctrine "user".

Но при выполнении функциональных тестов: $this->container->get('security.token_storage')->getToken()->getUser() — это строка, содержащая имя пользователя, а $this->getUser() — это NULL.

Что мне нужно сделать, чтобы поведение в моем приложении и функциональных тестах было согласованным?


person Andy Preston    schedule 19.05.2015    source источник
comment
Попробуйте этот способ при выполнении вашего запроса: $client->request('GET', '/post/12', array(), array(), array( 'PHP_AUTH_USER' => 'username', 'PHP_AUTH_PW' => 'pa$$word', ));   -  person smarber    schedule 19.05.2015


Ответы (1)


Посмотрите на источник UsernamePasswordToken:

class UsernamePasswordToken extends AbstractToken
{

    /**
     * Constructor.
     *
     * @param string|object            $user        The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method.
     * @param string                   $credentials This usually is the password of the user
     * @param string                   $providerKey The provider key
     * @param RoleInterface[]|string[] $roles       An array of roles
     *
     * @throws \InvalidArgumentException
     */
    public function __construct($user, $credentials, $providerKey, array $roles = array())

особенно описание параметра $user

@param string|object $user Имя пользователя (например, псевдоним, адрес электронной почты и т. д.), экземпляр UserInterface или объект.

Таким образом, при использовании приложения вы передаете объект пользователя в качестве параметра $user, но вы передаете строку электронной почты в своем тесте.

Итак, первый способ — создать новый пользовательский объект и заполнить его некоторыми тестовыми данными или получить определенного пользователя из его репозитория, например:

$user = $client->getContainer()->get('doctrine')->getManager()->getRepository('MyAppUserBundle:User')->findOneByEmail('[email protected]');
$token = new UsernamePasswordToken($user, null, $firewall, array('ROLE_USER', 'ROLE_ADMIN'));
person Evgeniy Kuzmin    schedule 19.05.2015
comment
Тогда простой ответ... просто передайте макет или реальный пользовательский объект конструктору UsernamePasswordToken вместо имени пользователя (как предлагается в документации Symfony2) - person Andy Preston; 20.05.2015
comment
Я попробовал то же решение здесь. Я получаю доступ к зарегистрированному пользователю внутри eventSubscriber getUser(), что дает null любое предложение - person somesh; 06.08.2019