2015-10-16 54 views
1

我试图以编程方式在SF 2.7和FOSUserBundle开发人员的功能测试中记录用户。我已经找到了一个很好的参考,通过SO登录用户在这个答案 - Symfony2 - Tests with FOSUserBundle以编程方式记录用户使用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

每当我给函数的getUser()控制器使用(

PHPstorm Xdebug Information null token

所以我决定试试下面的代码登录用户,和它的作品:http://api.symfony.com/2.7/Symfony/Bundle/FrameworkBundle/Controller/Controller.html#method_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(); 

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

谢谢!

+0

我唯一可以看到这就是不同的,以我怎么做是你的调用容器再次。我想知道由于某种原因它是否超出范围。尝试在开始时将容器存储在类私有成员中,然后从那里调用它。 – DevDonkey

+0

好点。我纠正了这一点,并添加了:$ container-> get('security.token_storage') - > setToken($ token);虽然,这似乎并没有解决它。有趣。 – Ratty

+0

您是否尝试创建记录用户的BaseTest?而且您始终可以从记录的用户客户端实例获取客户端。所以你不需要登录每个测试。 –

回答

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

你在这里找到了,我猜... https://advancingusability.wordpress.com/2013/11/15/functional-testing-with-authentication-and-symfony-2-3-fosuserbundle/ – mika

相关问题