用 phpunit 模拟 symfony 安全,返回空值而不是布尔值(不使用预言)

Posted

技术标签:

【中文标题】用 phpunit 模拟 symfony 安全,返回空值而不是布尔值(不使用预言)【英文标题】:Mocking symfony security with phpunit, return null value instead of bool (not using prophecy) 【发布时间】:2021-08-07 21:57:54 【问题描述】:

我有一个验证器,它调用 symfony 安全组件的多个方法。

我正在用 phpunit 模拟它。 getUser 工作正常,但我似乎无法使用 isGranted 返回布尔值。 它仅适用于willReturn(true)

如果我使用will($this->returnValueMap($map)),它会说: TypeError: Return value of Mock_Security_ccdbfb27::isGranted() must be of the type bool, null returned

如果我使用willReturn($this->returnValueMap($map)),我会得到: Method isGranted may not return value of type PHPUnit\Framework\MockObject\Stub\ReturnValueMap, its return declaration is ": bool"

如果我尝试使用回调,也会出现同样的问题。

private function getValidator(string $loggedUserRole, bool $expectsViolation)
    
        $map = [
            ['ROLE_ADMIN', $loggedUserRole === 'ADMIN'],
            ['ROLE_MANAGER', ($loggedUserRole === 'ADMIN' || $loggedUserRole === 'MANAGER')],
        ];

        $security = $this->createMock(Security::class);
        $security
            ->method('getUser')
            ->willReturn($loggedUserRole === 'ANONYMOUS'? null : (new User()));

        $security
            ->expects($this->any())
            ->method('isGranted')
            ->will($this->returnValueMap($map));

        $validator = new ValidatorClass($security);
        $context = $this->getContext($expectsViolation);
        $validator->initialize($context);
        return $validator;
    

【问题讨论】:

【参考方案1】:

我遇到了类似的问题。

“isGranted”方法有第二个输入参数(主题),默认为“null”。您必须将此作为第二个值包含在参数映射中,第三个将作为结果。

所以在你的情况下:

$map = [
  ['ROLE_ADMIN', null,  $loggedUserRole === 'ADMIN'],
  ['ROLE_MANAGER', null, ($loggedUserRole === 'ADMIN' || $loggedUserRole === 'MANAGER')],
];

【讨论】:

以上是关于用 phpunit 模拟 symfony 安全,返回空值而不是布尔值(不使用预言)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 symfony phpunit kernelTestCase 中正确注入 monolog.logger / LoggerInterface 作为模拟

Symfony PHPUnit 测试不验证用户

Symfony 5 Phpunit 未定义方法

Symfony:如何正确地从phpunit / phpunit切换到phpunit桥

PHPUnit、接口和命名空间 (Symfony2)

应该将 phpunit 或石灰与 symfony 一起使用吗? [关闭]