12

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;

それから私は検索して検索しました...私の2回目の試み。

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;

前もって感謝します。

4

2 に答える 2

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();
}
于 2013-02-19T16:03:37.557 に答える
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()
        );
    }
}

この方法はテストされ、正常に機能します

于 2014-12-01T07:06:21.450 に答える