首页 > 解决方案 > 在 PhpUnit 中测试令牌过期的正确方法

问题描述

我已经编写了获取 JWT 令牌并将其缓存 59 分钟的服务。我现在正在为此服务编写测试。在我的 AuthService 中,我有 2 种方法:

public function getToken(): string
    {
        $token = $this->cache->getItem('access_token');
        // Czy jest token w cache
        if ($token->isHit()) {
            return $token->get();
        } else {
            $newToken = $this->getNewToken();
            $this->saveTokenInCache($newToken);
            return $newToken;
        }
    }

private function saveTokenInCache($tokenToSave): void
    {
        $savedToken = $this->cache->getItem('access_token');
        $savedToken->set($tokenToSave);
        $savedToken->expiresAfter(3540);
        $this->cache->save($savedToken);
   }

我有一个测试:

 /**
     * @test
     */
    public function new_token_should_be_fetched_after_expiration()
    {
        $this->msGraphAuthService->expects($this->exactly(2))
            ->method('getNewToken');
        // getToken
        $this->msGraphAuthService->getToken();
        // change time
        $date = new DateTime();
        $date->modify('3541 seconds');
        $this->msGraphAuthService->getToken();

    }

对于我正在使用的缓存FileSystemAdapter

带有模拟getNewToken方法的设置功能是:

protected function setUp(): void
    {
        $kernel = self::bootKernel();
        $this->cacheService = new FilesystemAdapter();
        $this->serializer = $kernel->getContainer()->get('serializer');
        $this->logger = $this->createMock(Logger::class);
        $this->msGraphAuthService =$this>getMockBuilder(MicrosoftGraphAuthService::class)
            ->onlyMethods(['getNewToken'])
            ->setConstructorArgs([$this->logger, "", "", "", ""])
            ->getMock();
        $this->msGraphAuthService
            ->method('getNewToken')
            ->willReturn('{"token_type":"Bearer","expires_in":3599,"ext_expires_in":3599,"access_token":"eyJ..."}');
    }

我在测试new_token_should_be_fetched_after_expiration中的确切目标是检查getNewToken方法是否已经被调用了 2 次,但是我怎么能比现在晚 59 分钟?

我试图做类似的事情:

 $date = new DateTime();
 $date->modify('3541 seconds');

但它不起作用。

我将不胜感激。

标签: phpsymfonytestingcachingphpunit

解决方案


看起来时间是getNewToken().

使依赖关系更明显。例如,无论是它$_SERVER['REQUEST_TIME']还是默认为它的更专用的$date参数(或您在实现中拥有的任何参数):

...
$date = new DateTime();
$token = $this->getNewToken($date);
...

然后,您可以轻松地创建即将过期、已经过期的令牌和/或您也可以删除时间对检查例程的隐藏依赖性。


推荐阅读