2016-11-02 141 views
1

我需要以测试每个角色对页面的正确访问写一个功能测试与模拟令牌身份验证时,正确设置的用户名。如何在功能测试

为了做到这一点,我simulating authentication with a token,但我有一点不同的登录方法,只是将其与定制$username$role$firewall拨打:

protected function logIn($username, $role, $firewall) 
{ 
    $session = $this->client->getContainer()->get('session'); 

    $token = new UsernamePasswordToken($username, null, $firewall, $role); 
    $session->set('_security_' . $firewall, serialize($token)); 
    $session->save(); 

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

所以我可以把它指定哪些角色应该有假的用户:

$this->logIn('[email protected]', ['ROLE_USER'], "my_firewall"); 

然后,我可以或测试,如果不允许用户不访问某些航线:

// check if the access is correctly denied to the ROLE_USER 
$this->client->request('GET', '/route-not-allowed-to-user'); 
     $this->assertEquals(403, $this->client->getResponse()->getStatusCode()); 

// check if the access is correctly allowed to the ROLE_USER 
$this->client->request('GET', '/route-allowed-to-user'); 
     $this->assertNotEquals(403, $this->client->getResponse()->getStatusCode()); 

那些断言工作,唯一的问题是,在route-allowed-to-user的观点我用树枝来输出用户名:

{{ app.user.username }}

,但它失败。我得到了状态代码500而不是让200,并出现以下错误:

Impossible to access an attribute ("username") on a null variable ...

因为app.user未设置。

如何模拟与令牌身份验证时,我设置正确的用户?

回答

0

我通过编辑logIn方法如下解析:

protected function logIn($username, $password, $firewall) 
{ 
    $session = $this->client->getContainer()->get('session'); 
    $authenticationManager = $this->client->getContainer()->get('security.authentication.manager'); 

    $token = $authenticationManager->authenticate(
     new UsernamePasswordToken(
      $username, 
      $password, 
      $firewall 
     ) 
    ); 

    $session->set('_security_' . $firewall, serialize($token)); 
    $session->save(); 

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

,并使用doctrine data fixtures以设置用户和角色。

0

我想这是因为你没有经过认证过程,只是创建了没有触发存储用户的用户名,角色等的Symfony的事件的用户令牌。

我最近做了类似的事情,通过实际经历的登录表单,填写资料并发送。就像我正在做一个真正的登录尝试,它运作良好。

use Symfony\Component\DependencyInjection\ContainerInterface; 

abstract class AuthenticatedTestCase extends KernelTestCase 
{ 
    static protected $client; 

    static public function setUpBeforeClass() 
    { 
     parent::setUpBeforeClass(); 
     self::$client = static::$kernel->getContainer()->get('test.client'); 
    } 

    static public function login($login, $password) 
    {  
     $crawler = self::$client->request('GET', '/test_admin/login'); 
     $form = $crawler->filter('input[type="submit"]')->form([ 
      '_username' => $login, 
      '_password' => $password, 
     ]); 

     self::$client->submit($form); 

     // Redirect after successful login 
     self::assertEquals(302, self::$client->getResponse()->getStatusCode()); 

     self::$client->followRedirect(); 

     if (200 === self::$client->getResponse()->getStatusCode()) { 
      // Redirected URL is OK 
      // ... 
     } 
    } 
}