Symfony2 - 使用FOSUserBundle进行测试

时间:2013-02-19 12:43:23

标签: unit-testing authentication symfony phpunit fosuserbundle

我会用FOSUserBundle为Symfony2写一个测试。

目前我尝试了一些方法而没有人工作。

我需要像" createAuthClient"。

这样的功能

这是我的基础课。 我发布它是因为你可以更好地理解我的问题。

<?php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\BrowserKit\Cookie;

class WebTestMain extends WebTestCase
{
    protected static $container;

    static protected function createClient(array $options = array(), array $server = array())
    {
        $client = parent::createClient($options, $server);

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

        return $client;
    }

    static function createAuthClient(array $options = array(), array $server = array())
    {
        // see lines below with my tries
    }
}

首先尝试:

if(static::$kernel === null)
{
    static::$kernel = static::createKernel($options);
    static::$kernel->boot();
}
if(static::$container === null)
{
    self::$container = self::$kernel->getContainer();
}

$parameters = self::$container->getParameter('test');
$server = array_merge(array('HTTP_HOST' => $parameters['host'], 'HTTP_USER_AGENT' => $parameters['useragent']), $server);

$client = self::createClient($options, $server);

$userProvider = self::$container->get('fos_user.user_manager');
$user = $userProvider->findUserBy(array('id' => 1));
$client->getCookieJar()->set(new Cookie('MOCKSESSID', true));
$session = self::$kernel->getContainer()->get('session');
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$client->getContainer()->get('security.context')->setToken($token);
$session->set('_security_main', serialize($token));

return $client;

然后我搜索并搜索了...... 我的第二次尝试。

if(static::$kernel === null)
{
    static::$kernel = static::createKernel($options);
    static::$kernel->boot();
}
if(static::$container === null)
{
    self::$container = self::$kernel->getContainer();
}

$parameters = self::$container->getParameter('test');
$server = array_merge(
    array(
        'HTTP_HOST' => $parameters['host'],
        'HTTP_USER_AGENT' => $parameters['useragent'],
        'PHP_AUTH_USER' => 'admin',
        'PHP_AUTH_PW'   => 'admin'
    ),
    $server
);
$client = static::createClient(array(), array());
$client->followRedirects();
return $client;

这是我发布此问题之前的最后一次尝试......

$client = self::createClient($options, $server);

$parameters = self::$container->getParameter('test');
$server = array_merge(
    array(
        'HTTP_HOST' => $parameters['host'],
        'HTTP_USER_AGENT' => $parameters['useragent']
    ),
    $server
);

$client->setServerParameters($server);

$usermanager = self::$container->get('fos_user.user_manager');
$testuser = $usermanager->createUser();
$testuser->setUsername('test');
$testuser->setEmail('test@mail.org');
$testuser->setPlainPassword('test');
$usermanager->updateUser($testuser);

return $client;

先谢谢你。

2 个答案:

答案 0 :(得分:17)

我发现使用经过身份验证的用户进行测试的最佳方法是访问您的登录页面并使用您从夹具加载的用户名和密码提交表单。这可能看起来很慢而且很麻烦,但会测试用户实际会做什么。您甚至可以创建自己的方法,以便快速轻松地使用它。

public function doLogin($username, $password) {
   $crawler = $this->client->request('GET', '/login');
   $form = $crawler->selectButton('_submit')->form(array(
       '_username'  => $username,
       '_password'  => $password,
       ));     
   $this->client->submit($form);

   $this->assertTrue($this->client->getResponse()->isRedirect());

   $crawler = $this->client->followRedirect();
}

答案 1 :(得分:15)

创建AbstractControllerTest并在setUp()上创建授权客户端,如下所示:

<?php
// ...
use Symfony\Component\BrowserKit\Cookie;

abstract class AbstractControllerTest extends WebTestCase
{
    /**
     * @var Client
     */
    protected $client = null;


    public function setUp()
    {
        $this->client = $this->createAuthorizedClient();
    }

    /**
     * @return Client
     */
    protected function createAuthorizedClient()
    {
        $client = static::createClient();
        $container = $client->getContainer();

        $session = $container->get('session');
        /** @var $userManager \FOS\UserBundle\Doctrine\UserManager */
        $userManager = $container->get('fos_user.user_manager');
        /** @var $loginManager \FOS\UserBundle\Security\LoginManager */
        $loginManager = $container->get('fos_user.security.login_manager');
        $firewallName = $container->getParameter('fos_user.firewall_name');

        $user = $userManager->findUserBy(array('username' => 'REPLACE_WITH_YOUR_TEST_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()));

        return $client;
    }
} 

注意:请用您的测试用户名替换用户名。

然后,扩展AbstractControllerTest并使用全局$client发出如下请求:

class ControllerTest extends AbstractControllerTest
{
    public function testIndexAction()
    {
        $crawler = $this->client->request('GET', '/admin/');

        $this->assertEquals(
            Response::HTTP_OK,
            $this->client->getResponse()->getStatusCode()
        );
    }
}

此方法经过测试并正常运行