2012-02-07 96 views

回答

0

這就是我是如何實現它的項目之一(不與FOSUserBundle,但可能你會發現它有用)

private function createAuthorizedClient($role) 
{ 
    $userProvider = new YourUserProvider(...); 
    $user = $userProvider->createUserMethod(...); 

    $client = $this->createClient(); //Normal WebTestCase client 
    $client->getCookieJar()->set(new Cookie(session_name(), true)); 
    $session = self::$kernel->getContainer()->get('session'); 
    $token = new UsernamePasswordToken($user, 'password', 'main', array($role)); 
    $client->getContainer()->get('security.context')->setToken($token); 
    $session->set('_security_main', serialize($token)); 

    return $client; 
} 

不要忘記嘲笑爲用戶對象預期的結果。

5

其實,認證必須像真正的用戶那樣完成。在這種情況下,你必須知道的明文口令,並填寫登錄表單

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; 
class XXX extends WebTestCase { 
    public function testUserLogin() { 

    $client = static::createClient(); 
    $client->request('GET', '/login'); 

    $form = $crawler->selectButton('_submit')->form(array(
    '_username' => 'user', 
    '_password' => 'pa$$word', 
    )); 

    $client->submit($form); 
    $crawler = $client->followRedirect(); // "/" page 

    // if credentials were correct, you should be logged in and ready to test your app 
    } 
} 
+0

在symfony 3.4中工作(謝謝!) – HTDutchy 2018-01-08 15:47:14

2

我知道這是爲時已晚。但萬一有人需要這個,我設法在像這樣我的單元測試LOGG用戶:

1 - 首先定義一個類,它會給您可以訪問服務:

<?php 
namespace Tests; 

class ContainerAwareUnitTestCase extends \PHPUnit_Framework_TestCase 
{ 
    protected static $kernel; 
    protected static $container; 

    public static function setUpBeforeClass() 
    { 
     self::$kernel = new \AppKernel('dev', true); 
     self::$kernel->boot(); 

     self::$container = self::$kernel->getContainer(); 
    } 

    public function get($serviceId) 
    { 
     return self::$kernel->getContainer()->get($serviceId); 
    } 
} 

2-然後宣佈測試如下:

<?php 

namespace Tests\Menu; 

use Tests\ContainerAwareUnitTestCase; 
use UserBundle\Entity\User; 
use FOS\UserBundle\Security\UserProvider; 
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; 
use Symfony\Component\Security\Core\SecurityContext; 
use Symfony\Component\HttpFoundation\Request; 
use Menu\MenuBuilder; 

class MenuBuilderTest extends ContainerAwareUnitTestCase 
{ 
    public function provider() 
    { 
     return array(array('/')); 

    } 

    /** 
    * @dataProvider provider 
    */ 
    public function testNoAuth($uri) 
    { 
     /* @var $securityContext SecurityContext */ 
     $securityContext = $this->get('security.context'); 
     $userProvider = $this->get('fos_user.user_provider.username'); 
     $user = $userProvider->loadUserByUsername('alex'); 
     $token = new UsernamePasswordToken($user, null, 'main', array('ROLE_USER')); 
     $securityContext->setToken($token); 

     /* @var $menuBuilder MenuBuilder */ 
     $menuBuilder = $this->get('event_flow_analyser.menu_builder'); 

     $this->assertNotNull($menuBuilder); 

     $request = new Request(); 
     $request->attributes->set('projectName', 'ucs'); 

     $menu = $menuBuilder->createMainMenu($request); 

     $this->assertNotNull($menu); 

     $this->assertNotNull($menu->getChild('Home')); 
     $this->assertNotNull($menu->getChild('Profile')); 

     $this->assertEquals(null, $menu->getChild('Projects')); 
    } 

}  

這是一個完整的爲例,測試使用MenuBuilder創作,不過雖然超出範圍了一點,即提取物應該回答你的需要:

 $securityContext = $this->get('security.context'); 
     $userProvider = $this->get('fos_user.user_provider.username'); 
     $user = $userProvider->loadUserByUsername('alex'); 
     $token = new UsernamePasswordToken($user, null, 'main', array('ROLE_USER')); 
     $securityContext->setToken($token); 
3

現有的這個問題的答案是有幫助的,但它們都沒有解決我的問題直。我正在使用Symfony 2.3。

這是我的解決方案:

<?php 

namespace CDE\TestBundle\Base; 

use FOS\UserBundle\Model\User; 
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; 
use Symfony\Component\BrowserKit\Cookie; 
use Symfony\Component\BrowserKit\CookieJar; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage; 
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; 

class BaseUserTest extends WebTestCase { 

    protected $client; 
    protected $container; 
    protected $storage; 
    protected $session; 
    protected $user; 
    protected $cookieJar; 
    protected $cookie; 
    protected $token; 

    public function __construct() { 
     $this->client = static::createClient(); 
     $this->container = $this->client->getContainer(); 
     $this->storage = new MockFileSessionStorage(__dir__.'/../../../../app/cache/test/sessions'); 
     $this->session = new Session($this->storage); 

    } 

    public function getUserManager() { 
     return $this->container->get('cde_user.manager.user'); 

    } 

    public function getSecurityManager() { 
     return $this->container->get('fos_user.security.login_manager'); 

    } 

    public function getUser($role = null) { 
     if (!isset($this->user)) { 
      $user = $this->getUserManager()->loadByUsername('user'); 

      if (isset($user)) { 
       $this->user = $user; 
      } else { 
       $this->user = $this->getUserManager()->create(); 

       $this->user->setEnabled(true); 
       $this->user->setUsername('user'); 
       $this->user->setEmail('[email protected]'); 
       $this->user->setPlainPassword('user'); 
       $this->getUserManager()->updatePassword($this->user); 
       if (isset($role)) { 
        $this->user->addRole($role); 
       } 
       $this->getUserManager()->add($this->user); 
      } 

     } 

     return $this->user; 
    } 

    public function logIn(User $user, Response $response) { 
     $this->session->start(); 

     $this->cookie = new Cookie('MOCKSESSID', $this->storage->getId()); 
     $this->cookieJar = new CookieJar(); 
     $this->cookieJar->set($this->cookie); 
     $this->token = new UsernamePasswordToken($user, 'user', 'main', $user->getRoles()); 
     $this->session->set('_security_main', serialize($this->token)); 


     $this->getSecurityManager()->loginUser(
      $this->container->getParameter('fos_user.firewall_name'), 
      $user, 
      $response 
     ); 

     $this->session->save(); 
    } 

    public function removeUser(User $user) { 

    } 
} 

RestControllerTest.php

<?php 

namespace CDE\ContentBundle\Tests\Controller; 

use CDE\TestBundle\Base\BaseUserTest; 
use Symfony\Component\HttpFoundation\Response; 

class RestControllerTest extends BaseUserTest 
{ 
    protected $comment; 

    public function __construct() { 
     parent::__construct(); 
     $this->logIn($this->getUser('ROLE_ADMIN'), new Response()); 

    } 

    public function getGalleryManager() { 
     return $this->container->get('cde_content.manager.gallery'); 
    } 

    public function getAWSManager() { 
     return $this->container->get('cde_utility.manager.aws'); 
    } 

    public function createGallery() 
    { 
     //  Copy test.jpeg into the web folder 
     $filename = 'gallery/user-test.jpg'; 
     copy(__DIR__.'/../Mock/test.jpeg', __DIR__.'/../../../../../web/'.$filename); 
     $this->getAWSManager()->copyGalleryFile($filename); 


     $gallery = $this->getGalleryManager()->create(); 
     $gallery->setUser($this->getUser()); 
     $gallery->setFilename($filename); 
     $gallery->setTitle('test gallery'); 
     $gallery->setDescription('test gallery description'); 
     $gallery->setMarked(false); 
     $this->getGalleryManager()->add($gallery); 
     $this->assertEquals($gallery->getMarked(), false); 
    } 

    public function createComment() 
    { 
     $galleries = $this->getGalleryManager()->findByUser($this->getUser()); 
     $gallery = $galleries[0]; 

     $client = static::createClient(); 
     $client->getCookieJar()->set($this->cookie); 
//  $client = static::createClient(array(), new History(), $cookieJar); 

     $crawler = $client->request('POST', 'api/createComment/'.$gallery->getId(), array(
      'comment' => 'testing testing 123', 
      'marked' => 'false' 
     )); 

     $response = $client->getResponse(); 
     $this->comment = json_decode($response->getContent()); 
     $this->assertEquals($this->comment->comment, 'testing testing 123'); 
     $this->assertFalse($this->comment->marked); 
     $this->assertEquals($response->getStatusCode(), 200); 
    } 

    public function getComment() 
    { 
     $client = static::createClient(); 

     $crawler = $client->request('GET', 'api/getComment/'.$this->comment->id); 

     $response = $client->getResponse(); 
     $comment = json_decode($response->getContent()); 
     $this->assertEquals($comment->comment, 'testing testing 123'); 
     $this->assertFalse($comment->marked); 
     $this->assertEquals($response->getStatusCode(), 200); 

    } 

    public function updateComment() 
    { 
     $client = static::createClient(); 

     $crawler = $client->request('GET', 'api/updateComment'); 
    } 

    public function deleteComment() 
    { 
     $client = static::createClient(); 

     $crawler = $client->request('DELETE', 'api/deleteComment'); 
    } 

    public function getComments() 
    { 
     $client = static::createClient(); 

     $crawler = $client->request('GET', 'api/getComments'); 
    } 

    public function getGalleries() 
    { 
     $client = static::createClient(); 

     $crawler = $client->request('GET', 'api/getGalleries'); 
    } 

    public function removeGallery() { 
     $galleries = $this->getGalleryManager()->findByUser($this->getUser()); 
     foreach ($galleries as $gallery) { 
      $this->getGalleryManager()->remove($gallery); 
     } 

    } 

    public function testComments() { 
     $this->createGallery(); 
     $this->createComment(); 
     $this->getComment(); 
     $this->updateComment(); 
     $this->deleteComment(); 
     $this->getComments(); 
     $this->getGalleries(); 
     $this->removeGallery(); 
    } 

} 

該代碼包括基礎測試類(BaseUserTest.php),其可以擴展到容易登錄的用戶。

我還介紹瞭如何在示例測試中使用基類的示例(RestControllerTest.php)。在RestControllerTest.php注意這個代碼塊:

$client = static::createClient(); 
$client->getCookieJar()->set($this->cookie); 

背後BaseUserTest的想法是,它可以創建它自己的會話,用用戶的會話,然後會話保存到使用MockFileSessionStorage文件系統。

測試本身必須在客戶端上設置cookie。

+0

嗨,我喜歡你的解決方案..你能不能粘貼一些與你有關的security.yml配置。 – r4ccoon 2016-06-02 18:55:46

0

由於我不能評論你的解決方案,我必須創建一個新的答案。實際上,其他解決方案是正確的,因爲他們使用功能測試來測試特定場景。您正在使用單元測試來測試屬於功能測試的場景,這就是爲什麼您必須破解用戶登錄。請考慮其他解決方案,並通過檢查正確的菜單項的DOM對象來進行功能測試。