authorizationChecker->isGranted 在 phpUnit 测试中
authorizationChecker->isGranted in a phpUnit test
我目前正在为我的应用程序创建单元测试,但这是我第一次这样做。
我想测试这个功能:
/**
* This method search if the user is already in a team for the same tournament than the one passed in argument
* @param User $user
* @param Team $team
* @return bool|Team|mixed
*/
public function isAlreadyApplicant($user, Team $team) {
if (!$user || !$this->authorizationChecker->isGranted("ROLE_USER")) {
return false;
}
foreach ($user->getApplications() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getTeams() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getManagedTeam() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
return false;
}
如您所见,第一个测试是检查用户是否拥有ROLE_USER。
当我尝试 "log my user" 时,我收到以下消息:
Fatal error: Call to a member function getToken() on null in \vendor\symfony\symfony\src\Symfony\Component\Security\Core\Authorization\AuthorizationChecker.php on line 56
我尝试了在 Symfony 文档中找到的内容,但我一定遗漏了一些东西。这是我的测试 Class:
class ApplicationCheckerTest extends WebTestCase
{
protected $client = null;
public function setUp() {
$this->client = static::createClient();
/** @var User $user */
$user = $this->client->getContainer()->get('doctrine')->getManager()->getRepository('MGDUserBundle:User')->findOneBy(array("email" => 'Player11.Player11@test.com'));
$this->loginUser("main", $user);
}
protected function loginUser($firewallName, UserInterface $user, array $options = array(), array $server = array())
{
$this->client = static::createClient();
$token = new UsernamePasswordToken($user, null, $firewallName, $user->getRoles());
static::$kernel->getContainer()->get('security.token_storage')->setToken($token);
$session = $this->client->getContainer()->get('session');
$session->set('_security_'.$firewallName, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
public function testIsAlreadyApplicantIsNotConnected()
{
$user = new User();
$team = new Team();
$router = $this->createMock(Router::class);
$authorizationChecker = $this->createMock(AuthorizationChecker::class);
$applicationChecker = new ApplicationChecker($router, $authorizationChecker);
$applicationChecker->isAlreadyApplicant($user, $team);
}
}
我的 security.yml 看起来像:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: true
provider: main
form_login:
login_path: fos_user_security_login
check_path: fos_user_security_check
logout:
path: fos_user_security_logout
target: /
remember_me:
secret: '%secret%'
我尝试连接我创建的用户与灯具。
我不确定我尝试这样做的方式,也许我走错了路,如果我错了请不要犹豫纠正我!
有关信息,我在 Symfony 3.2.13
祝你有美好的一天
WebTestCase
和您正在使用的 Symfony 文档中的示例应该用于控制器的功能测试。
您为客户端设置身份验证的方式正确。但是您没有使用该客户端向测试用例中的自举 Symfony 内核发出请求。您只是在手动创建的服务实例上进行简单的单元测试,这很好。
您只需使用 PHPUnit\Framework\TestCase
即可。
可以使用 WebTestCase
来测试您的服务,并在内核容器而不是客户端容器中覆盖 AuthorizationChecker
中使用的 TokenStorage
,然后还可以从内核容器中获取您的服务,而不是自己实例化它。但我看不出有什么好处。无需测试 Symfony 组件(如果 isGranted 正在运行)。这在 Symfony 项目的范围内,很可能已经涵盖在那里。
你的错误
您出错的原因是无法模拟 final 方法。作为解决方法,您可以将 ApplicationChecker
构造函数中的依赖项设置为 AuthorizationCheckerInterface
,然后从测试中的界面创建一个模拟。
$authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
$authorizationChecker->method('isGranted')->willReturn(true);
我目前正在为我的应用程序创建单元测试,但这是我第一次这样做。
我想测试这个功能:
/**
* This method search if the user is already in a team for the same tournament than the one passed in argument
* @param User $user
* @param Team $team
* @return bool|Team|mixed
*/
public function isAlreadyApplicant($user, Team $team) {
if (!$user || !$this->authorizationChecker->isGranted("ROLE_USER")) {
return false;
}
foreach ($user->getApplications() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getTeams() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getManagedTeam() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
return false;
}
如您所见,第一个测试是检查用户是否拥有ROLE_USER。
当我尝试 "log my user" 时,我收到以下消息:
Fatal error: Call to a member function getToken() on null in \vendor\symfony\symfony\src\Symfony\Component\Security\Core\Authorization\AuthorizationChecker.php on line 56
我尝试了在 Symfony 文档中找到的内容,但我一定遗漏了一些东西。这是我的测试 Class:
class ApplicationCheckerTest extends WebTestCase
{
protected $client = null;
public function setUp() {
$this->client = static::createClient();
/** @var User $user */
$user = $this->client->getContainer()->get('doctrine')->getManager()->getRepository('MGDUserBundle:User')->findOneBy(array("email" => 'Player11.Player11@test.com'));
$this->loginUser("main", $user);
}
protected function loginUser($firewallName, UserInterface $user, array $options = array(), array $server = array())
{
$this->client = static::createClient();
$token = new UsernamePasswordToken($user, null, $firewallName, $user->getRoles());
static::$kernel->getContainer()->get('security.token_storage')->setToken($token);
$session = $this->client->getContainer()->get('session');
$session->set('_security_'.$firewallName, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
public function testIsAlreadyApplicantIsNotConnected()
{
$user = new User();
$team = new Team();
$router = $this->createMock(Router::class);
$authorizationChecker = $this->createMock(AuthorizationChecker::class);
$applicationChecker = new ApplicationChecker($router, $authorizationChecker);
$applicationChecker->isAlreadyApplicant($user, $team);
}
}
我的 security.yml 看起来像:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: true
provider: main
form_login:
login_path: fos_user_security_login
check_path: fos_user_security_check
logout:
path: fos_user_security_logout
target: /
remember_me:
secret: '%secret%'
我尝试连接我创建的用户与灯具。
我不确定我尝试这样做的方式,也许我走错了路,如果我错了请不要犹豫纠正我!
有关信息,我在 Symfony 3.2.13
祝你有美好的一天
WebTestCase
和您正在使用的 Symfony 文档中的示例应该用于控制器的功能测试。
您为客户端设置身份验证的方式正确。但是您没有使用该客户端向测试用例中的自举 Symfony 内核发出请求。您只是在手动创建的服务实例上进行简单的单元测试,这很好。
您只需使用 PHPUnit\Framework\TestCase
即可。
可以使用 WebTestCase
来测试您的服务,并在内核容器而不是客户端容器中覆盖 AuthorizationChecker
中使用的 TokenStorage
,然后还可以从内核容器中获取您的服务,而不是自己实例化它。但我看不出有什么好处。无需测试 Symfony 组件(如果 isGranted 正在运行)。这在 Symfony 项目的范围内,很可能已经涵盖在那里。
你的错误
您出错的原因是无法模拟 final 方法。作为解决方法,您可以将 ApplicationChecker
构造函数中的依赖项设置为 AuthorizationCheckerInterface
,然后从测试中的界面创建一个模拟。
$authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
$authorizationChecker->method('isGranted')->willReturn(true);