FOSUserBundle - PHPUnit - 模拟用户 - 无用户提供者
FOSUserBundle - PHPUnit - Mock a user - No User Provider
我正在将 Symfony 3.2 与 FOSUserBundle 一起使用,我正在尝试为需要在特定角色中进行身份验证的功能编写功能测试。
我使用了@tftd here 发布的方法,但是当我 运行 进行 phpunit 测试时,出现 500 错误:There is no user provider for user "Symfony\Component\Security\Core\User\User".
我的 webTestCase class 看起来像这样:
abstract class CustomWebTestCase extends WebTestCase
{
/**
* @param array|null $roles
* @return \Symfony\Bundle\FrameworkBundle\Client
*
*
*/
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);
$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 = 'main'; // 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;
}
我的测试例程如下所示:
class TryoutAdminControllerTest extends CustomWebTestCase
{
public function testTryoutListAction()
{
$authenticatedClient = self::createAuthenticatedClient(array('ROLE_USER'));
$crawler = $authenticatedClient->request('GET', '/admin/tryout');
$this->assertEquals(302, $authenticatedClient->getResponse()->getStatusCode(), 'No access allowed!');
$authorizedClient = self::createAuthenticatedClient(array('ROLE_ADMIN'));
$crawler = $authorizedClient->request('GET', '/admin/tryout');
$this->assertEquals(200, $authorizedClient->getResponse()->getStatusCode(), 'Access granted!');
}
}
security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
switch_user: true
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /
domain: ~
user_provider: fos_userbundle
最后 config_test.yml
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
如果有人能告诉我我遗漏了什么,我将不胜感激!
您可能需要在 WebTestCase
中实例化您自己的用户 class,它从 FOS\UserBundle\Model\User
而不是 Symfony\Component\Security\Core\User\User
扩展,因为您使用的是 FosUserBundle 用户提供程序。
考虑使用测试数据库和数据装置,因为您可能需要它来进行功能测试。 LiipFunctionalTestBundle 可能会有帮助。
请记住,正如问题标题中所建议的那样,此测试中没有模拟任何内容。必须在单元测试中使用模拟,而不是在功能测试中使用。
我正在将 Symfony 3.2 与 FOSUserBundle 一起使用,我正在尝试为需要在特定角色中进行身份验证的功能编写功能测试。
我使用了@tftd here 发布的方法,但是当我 运行 进行 phpunit 测试时,出现 500 错误:There is no user provider for user "Symfony\Component\Security\Core\User\User".
我的 webTestCase class 看起来像这样:
abstract class CustomWebTestCase extends WebTestCase
{
/**
* @param array|null $roles
* @return \Symfony\Bundle\FrameworkBundle\Client
*
*
*/
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);
$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 = 'main'; // 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;
}
我的测试例程如下所示:
class TryoutAdminControllerTest extends CustomWebTestCase
{
public function testTryoutListAction()
{
$authenticatedClient = self::createAuthenticatedClient(array('ROLE_USER'));
$crawler = $authenticatedClient->request('GET', '/admin/tryout');
$this->assertEquals(302, $authenticatedClient->getResponse()->getStatusCode(), 'No access allowed!');
$authorizedClient = self::createAuthenticatedClient(array('ROLE_ADMIN'));
$crawler = $authorizedClient->request('GET', '/admin/tryout');
$this->assertEquals(200, $authorizedClient->getResponse()->getStatusCode(), 'Access granted!');
}
}
security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
switch_user: true
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /
domain: ~
user_provider: fos_userbundle
最后 config_test.yml
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
如果有人能告诉我我遗漏了什么,我将不胜感激!
您可能需要在 WebTestCase
中实例化您自己的用户 class,它从 FOS\UserBundle\Model\User
而不是 Symfony\Component\Security\Core\User\User
扩展,因为您使用的是 FosUserBundle 用户提供程序。
考虑使用测试数据库和数据装置,因为您可能需要它来进行功能测试。 LiipFunctionalTestBundle 可能会有帮助。
请记住,正如问题标题中所建议的那样,此测试中没有模拟任何内容。必须在单元测试中使用模拟,而不是在功能测试中使用。