I've written service for getting JWT token and caching it for 59 minutes. I'm writing now a tests for this service. In my AuthService i have 2 methods:
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);
}
and I have a test:
/**
* @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();
}
For Cache I'm using FileSystemAdapter
.
Setup Function with mock of getNewToken
method is:
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..."}');
}
My exact goal in test new_token_should_be_fetched_after_expiration is to check if getNewToken method has been invoked exactly 2 times but how could I move time forward 59 minutes later than now?
I tried to do something like:
$date = new DateTime();
$date->modify('3541 seconds');
but it dosen't work.
I would be grateful for help.
It looks like time is a hidden dependency of getNewToken()
.
Make the dependency more visible. E.g. be it $_SERVER['REQUEST_TIME']
or a more dedicated $date
parameter that defaults to it (or whatever you have in the implementation):
...
$date = new DateTime();
$token = $this->getNewToken($date);
...
You can then easily create tokens that expire soon, have expired already and/or you can remove the hidden dependency of time on the check routine as well.