FOSUserBundle - PHPUnit - 模拟用户 [英] FOSUserBundle - PHPUnit - Mock a user
问题描述
我正在使用带有 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 WebTestCase
的 CustomWebTestCase
.在课堂上,我将创建一个为我进行身份验证的方法.
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.yml
framework.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屋!