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

时间:2015-10-16 14:24:47

标签: php symfony fosuserbundle functional-testing

我试图在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"
    );

}
}

每当我在路由执行之前设置断点时,令牌都会正确返回: PHPStorm Xdebug Output for token

每当我到达Controller(http://api.symfony.com/2.7/Symfony/Bundle/FrameworkBundle/Controller/Controller.html#method_getUser)使用的函数getUser()时,PHPStorm返回一个空令牌,如下所示:

PHPstorm Xdebug Information null token

所以我决定尝试使用以下代码来记录用户,并且它可以正常工作。

    $crawler = $this->client->request('GET', '/login');

    $form = $crawler->selectButton('_submit')->form(array(
        '_username'  => 'test',
        '_password'  => 'test123',
    ));

    $this->client->submit($form);
    $this->client->followRedirect(); 

每当我以编程方式登录用户时,我都没有正确地做某事吗?会话没有正确设置吗?

谢谢!

大鼠

1 个答案:

答案 0 :(得分:0)

我用这个:

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..
}