Symfony - 测试投票 TokenInterface 未调用

问题描述 投票:0回答:1

我正在尝试在我的

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);
我从数据库获取用户对象时..

php symfony phpunit symfony-voter
1个回答
1
投票

我无法写评论,所以我会发布答案。 我有一种感觉,我们需要查看您完整的 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 方法之前执行。因此,您无法访问从数据提供程序中创建的任何变量。

© www.soinside.com 2019 - 2024. All rights reserved.