Php 使用FOSUserBundle以编程方式登录用户进行功能测试

Php 使用FOSUserBundle以编程方式登录用户进行功能测试,php,symfony,fosuserbundle,functional-testing,Php,Symfony,Fosuserbundle,Functional Testing,我试图在SF 2.7和FOSUserBundle开发主机的功能测试中以编程方式登录用户。我已经找到了一个很好的用户登录via的参考资料,因此在这个答案中- 问题是第二个答案,即以编程方式登录用户,不起作用。这是我的密码: <?php namespace Test\BackEnd\UserBundle\Controller; use Test\Shared\CoreBundle\Tests\AbstractControllerTest; use Doctrine\Common\DataF

我试图在SF 2.7和FOSUserBundle开发主机的功能测试中以编程方式登录用户。我已经找到了一个很好的用户登录via的参考资料,因此在这个答案中-

问题是第二个答案,即以编程方式登录用户,不起作用。这是我的密码:

<?php

namespace Test\BackEnd\UserBundle\Controller;

use Test\Shared\CoreBundle\Tests\AbstractControllerTest;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Loader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\Tools\SchemaTool;
use FA\BackEnd\UserBundle\DataFixtures\ORM\LoadUserData;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

class DefaultController extends AbstractControllerTest
{

public function setUp()
{
    $this->client = static::createClient();

    $container = $this->client->getContainer();

    $doctrine = $container->get('doctrine');
    $em = $doctrine->getManager();
    $schemaTool = new SchemaTool($em);
    $metadata = $em->getMetaDataFactory()->getAllMetadata();

    // Drop and recreate tables for all entities
    $schemaTool->dropSchema($metadata);
    $schemaTool->createSchema($metadata);

    $loader = new Loader();
    $user = new LoadUserData();
    $user->setContainer($container);
    $loader->addFixture($user);

    $purger = new ORMPurger();
    $executor = new ORMExecutor($em, $purger);
    $executor->execute($loader->getFixtures());

    $session = $container->get('session');
    $userManager = $container->get('fos_user.user_manager');

    $user = $userManager->findUserBy(array('username' => 'test'));

    $firewall = 'default';

    $token = new UsernamePasswordToken($user, $user->getPassword(), $firewall, $user->getRoles());
    self::$kernel->getContainer()->get('security.token_storage')->setToken($token);
    $session->set('_security_'.$firewall, serialize($token));
    $session->save();

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

public function testProfile()
{
    //$this->createAuthorizedClient();

    $token = $this->client->getContainer()->get('security.token_storage')->getToken();

    $this->client->request('GET', '/profile/');

    $this->assertEquals(
        200,
        $this->client->getResponse()->getStatusCode(),
        "/profile isn't accessible"
    );

}
}
当我以编程方式登录用户时,我是否没有正确地执行某些操作?会话设置是否不正确

谢谢

老鼠

我用这个:

protected function createAuthorizedClient()
    {
     $client = static::createClient();
     $container = $client->getContainer();

     $session = $container->get('session');
     $userManager = $container->get('fos_user.user_manager');
     $loginManager = $container->get('fos_user.security.login_manager');
     $firewallName = $container->getParameter('fos_user.firewall_name');

     $user = $userManager->findUserBy(array('username' => 'USERNAME'));
     $loginManager->loginUser($firewallName, $user);

     // save the login token into the session and put it in a cookie
     $container->get('session')->set('_security_' . $firewallName, 
     serialize($container->get('security.context')->getToken()));
     $container->get('session')->save();
     $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
     $this->client = $client;
}
然后在你的测试中:

public function testMiInfo()
{
    $this->createAuthorizedClient();
    //else..
}
我用这个:

protected function createAuthorizedClient()
    {
     $client = static::createClient();
     $container = $client->getContainer();

     $session = $container->get('session');
     $userManager = $container->get('fos_user.user_manager');
     $loginManager = $container->get('fos_user.security.login_manager');
     $firewallName = $container->getParameter('fos_user.firewall_name');

     $user = $userManager->findUserBy(array('username' => 'USERNAME'));
     $loginManager->loginUser($firewallName, $user);

     // save the login token into the session and put it in a cookie
     $container->get('session')->set('_security_' . $firewallName, 
     serialize($container->get('security.context')->getToken()));
     $container->get('session')->save();
     $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
     $this->client = $client;
}
然后在你的测试中:

public function testMiInfo()
{
    $this->createAuthorizedClient();
    //else..
}

我能看到的唯一不同于我的做法是你再次呼叫容器。我想知道它是否出于某种原因超出了范围。尝试在开始时将容器存储在类私有成员中,并从那里调用它。这一点很好。我纠正了这一点,并添加了:$container->get('security.token\u storage')->setToken($token);尽管如此,这似乎并没有解决问题。有趣。您是否尝试创建一个记录用户日志的BaseTest?并且您始终可以从记录的用户客户端实例获取客户端。所以你不需要每次都登录测试。我能看到的唯一不同于我的方法是你再次调用容器。我想知道它是否出于某种原因超出了范围。尝试在开始时将容器存储在类私有成员中,并从那里调用它。这一点很好。我纠正了这一点,并添加了:$container->get('security.token\u storage')->setToken($token);尽管如此,这似乎并没有解决问题。有趣。您是否尝试创建一个记录用户日志的BaseTest?并且您始终可以从记录的用户客户端实例获取客户端。所以你不需要登录每个测试。我想你在这里找到的。。。你在这里找到的,我想。。。