我正在尝试在我的
Symfony项目中为 Voter 类编写一个
PHPUnit
测试。
class CustomVoter extends Voter
{
private MyCustomRepository $myCustomRepository;
public function __construct(MyCustomRepository $myCustomRepository)
{
$this->myCustomRepository = $myCustomRepository;
}
protected function supports(
string $attribute,
$subject
): bool
{
if (!in_array($attribute, ['edit'])) {
return false;
}
return true;
}
protected function voteOnAttribute(
string $attribute,
$subject,
TokenInterface $token
): bool
{
$user = $token->getUser();
if (!$user instanceof UserInterface) {
return false;
}
return $this->myCustomRepository->hasAccess(
$user->getId(),
$attribute,
$subject
);
}
}
我在嘲笑方面遇到问题
TokenInterface
。
在我的测试中,我从测试数据库返回一个用户:
private $entityManager;
protected TokenInterface|MockObject|null $token = null;
public function setUp(): void
{
$kernel = self::bootKernel();
$this->entityManager = $kernel->getContainer()
->get('doctrine')
->getManager();
$user = $this->entityManager
->getRepository(Member::class)
->findOneBy(['email' => '[email protected]']);
$this->token = $this->getMockBuilder(TokenInterface::class)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->disallowMockingUnknownTypes()
->getMock();
$this->token->expects($this->once())
->method('getUser')
->willReturn($user);
}
当尝试测试选民时:
/**
* @dataProvider provideCases
*/
public function testVote(array $attributes, string $subject, ?TokenInterface $token, $expectedVote) {
$this->assertEquals($expectedVote, $this->voter->vote($token, $subject, $attributes));
}
public function provideCases(): \Generator
{
yield 'user can edit' => [
['edit'],
'my_subject',
$this->token,
VoterInterface::ACCESS_GRANTED,
];
}
我得到:
调用 1 次时,方法名称为“getUser”的预期失败。 方法预计被调用 1 次,实际调用 0 次。
这是什么情况?当
dd($user);
我从数据库获取用户对象时..
我无法写评论,所以我会发布答案。 我有一种感觉,我们需要查看您完整的 Voter 类代码才能了解发生了什么。
我认为由于错误的属性或其他原因, vote() 方法提前完成了检查(在 voteOnAttribute() 调用之前),因此在您的情况下不会调用 getUser() 。
如果我知道如何帮助您,我会尝试编辑或删除此答案。
我在本地环境中测试了您的案例,我可以说您应该直接在测试方法中传递令牌,而不是通过 dataProvider 。
/**
* @dataProvider provideCases
*/
public function testVote(array $attributes, string $subject, $expectedVote) {
$this->assertEquals($expectedVote, $this->voter->vote($this->token, $subject, $attributes));
}
我们可以从文档中读到:
所有数据提供程序都在调用 setUpBeforeClass 静态方法和第一次调用 setUp 方法之前执行。因此,您无法访问从数据提供程序中创建的任何变量。