使用 FOSUserBundle 以编程方式记录用户以进行功能测试
Posted
技术标签:
【中文标题】使用 FOSUserBundle 以编程方式记录用户以进行功能测试【英文标题】:Logging a User in Programmatically for a Functional Test with FOSUserBundle 【发布时间】:2015-10-16 14:24:46 【问题描述】:我正在尝试在我对 SF 2.7 和 FOSUserBundle dev-master 的功能测试中以编程方式登录用户。我已经在这个答案中找到了一个很好的参考来通过 SO 登录用户 - Symfony2 - Tests with FOSUserBundle
问题是第二个答案,以编程方式登录用户,不起作用。这是我的代码:
<?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"
);
每当我在路由执行之前设置断点时,令牌都会正确返回:
每当我使用控制器 (http://api.symfony.com/2.7/Symfony/Bundle/FrameworkBundle/Controller/Controller.html#method_getUser) 使用的函数 getUser() 时,PHPStorm 都会返回一个空令牌,如下所示:
所以我决定尝试下面的代码来让用户登录,它可以工作。
$crawler = $this->client->request('GET', '/login');
$form = $crawler->selectButton('_submit')->form(array(
'_username' => 'test',
'_password' => 'test123',
));
$this->client->submit($form);
$this->client->followRedirect();
每当我以编程方式登录用户时,我是否没有正确地做某事?会话设置不正确吗?
谢谢!
老鼠
【问题讨论】:
我能看到的唯一与我的做法不同的是您再次调用容器。我想知道它是否出于某种原因超出了范围。尝试在开始时将容器存储在类私有成员中并从那里调用它。 好点。我更正了这一点并添加了: $container->get('security.token_storage')->setToken($token);虽然,这似乎并没有解决它。很有趣。 您是否尝试创建记录用户的 BaseTest?而且您始终可以从登录的用户客户端实例中获取客户端。所以你不需要每次测试都登录。 【参考方案1】:我用这个:
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..
【讨论】:
你在这里找到的,我猜...advancingusability.wordpress.com/2013/11/15/…以上是关于使用 FOSUserBundle 以编程方式记录用户以进行功能测试的主要内容,如果未能解决你的问题,请参考以下文章