FOSUserBundle - PHPUnit - 模拟用户 [英] FOSUserBundle - PHPUnit - Mock a user

查看:20
本文介绍了FOSUserBundle - PHPUnit - 模拟用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 FOSUserBundle 的 Symfony,现在我想测试一些东西,例如:

I am using Symfony with the FOSUserBundle and now I like to test some things like:

  • 学说生命周期
  • 防火墙后的控制器

对于这些测试,我需要成为特定用户或至少在用户组中.如何模拟用户会话,以便...

For those tests I need to be a specific user or at least in a user group. How do I mock a user session so that ...

  • createdAt"等生命周期字段将使用登录用户
  • 控制器的行为就像是某个模拟用户已登录

例子:

class FooTest extends ... {
    function setUp() {
        $user = $this->getMock('User', ['getId', 'getName']);

        $someWhereGlobal->user = $user;

        // after this you should be logged in as a mocked user
        // all operations should run using this user.
    }
}

推荐答案

在这种情况下,我要做的是创建一个扩展 Symfony WebTestCaseCustomWebTestCase.在课堂上,我将创建一个为我进行身份验证的方法.

What I would do in this case is to create a CustomWebTestCase which extends the Symfony WebTestCase. In the class I would create a method which does the authentication for me.

这是一个示例代码:

namespace CompanyMyBundleClasses;

use SymfonyBundleFrameworkBundleClient;
use SymfonyBundleFrameworkBundleTestWebTestCase;
use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken;
use SymfonyComponentBrowserKitCookie;
use SymfonyComponentSecurityCoreRoleRole;
use SymfonyComponentSecurityCoreUserUser;

abstract class CustomWebTestCase extends WebTestCase
{

    /**
     * @param array|null $roles
     * @return SymfonyBundleFrameworkBundleClient
     */
    protected static function createAuthenticatedClient(array $roles = null) {
        // Assign default user roles if no roles have been passed.
        if($roles == null) {
            $role = new Role('ROLE_SUPER_ADMIN');
            $roles = array($role);
        } else {
            $tmpRoles = array();
            foreach($roles as $role)
            {
                $role = new Role($role, $role);
                $tmpRoles[] = $role;
            }
            $roles = $tmpRoles;
        }

        $user = new User('test_super_admin', 'passwd', $roles);

        return self::createAuthentication(static::createClient(), $user);
    }

    private static function createAuthentication(Client $client, User $user) {
        // Read below regarding config_test.yml!
        $session = $client->getContainer()->get('session');

        // Authenticate
        $firewall = 'user_area'; // This  MUST MATCH the name in your security.firewalls.->user_area<-
        $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
        $session->set('_security_'.$firewall, serialize($token));
        $session->save();

        // Save authentication
        $cookie = new Cookie($session->getName(), $session->getId());
        $client->getCookieJar()->set($cookie);

        return $client;
    }
}

上面的代码将直接创建一个有效的用户会话,并完全跳过防火墙.因此,您可以创建任何您想要的 $user 并且它仍然有效.代码的重要部分位于方法 createAuthentication 中.这就是身份验证的魔力.

The code above will directly create a valid user session and will skip the firewall entirely. Therefore you can create whatever $user you want and it will still be valid. The important part of the code is located in the method createAuthentication. This is what does the authentication magic.

还有一点值得一提——确保在 config_test.ymlframework.session.storage_id 设置为 session.storage.mock_file> 这样 Symfony 将自动模拟会话,而不是您必须在每个测试用例中处理它:

One more thing worth mentioning - make sure you have set framework.session.storage_id to session.storage.mock_file in your config_test.yml so that Symfony will automatically mock sessions instead of you having to deal with that in each test case:

framework:
    session:
        storage_id: session.storage.mock_file

现在在您的测试用例中,您只需扩展 MyWebTestCase 并调用 createAuthenticatedClient() 方法:

Now in your test case you would simply extend MyWebTestCase and call the createAuthenticatedClient() method:

class MyTest extends CustomWebTestCase {
    public function testSomething() {
        //Create authoried and unauthorized clients.
        $authenticatedClient = self::createAuthenticatedClient(array("ROLE_SUPER_ADMIN"));
        $unauthorizedClient = self::createAuthenticatedClient(array("ROLE_INSUFFICIENT_PERMISSIONS"));

        // Check if the page behaves properly when the user doesn't have necessary role(s).
        $unauthorizedClient->request('GET', '/secured-page');
        $response = $unauthorizedClient->getResponse();
        $this->assertFalse($response->isSuccessful());
        $this->assertEquals(403, $response->getStatusCode(), "This request should have failed!");

        // Check if the page behaves properly when the user HAS the necessary role(s)
        $authenticatedClient->request('GET', '/secured-page');
        $response = $authenticatedClient->getResponse();
        $this->assertTrue($response->isSuccessful());
        $this->assertEquals(200, $response->getStatusCode(), "This request should be working!");
    }
}

你可以在 Symfony 官方文档中看到一个例子好吧.

You can see an example in the Symfony official documentation as well.

这篇关于FOSUserBundle - PHPUnit - 模拟用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆