Value object that depends on system time:
<?php
declare(strict_types=1);
namespace Xthiago;
final class BirthDate
{
private DateTimeImmutable $date;
protected function __construct(DateTimeImmutable $date)
{
$this->date = $date;
}
public function age(Clock $clock) : int
{
$interval = $this->date->diff($clock->now());
return $interval->y;
}
}
Clock service interface - where the Value Object rely on:
<?php
declare(strict_types=1);
namespace Xthiago;
use DateTimeImmutable;
interface Clock
{
public function now() : DateTimeImmutable;
}
FrozenClock - implementation of service for tests
<?php
declare(strict_types=1);
namespace Xthiago;
use DateTimeImmutable;
class FrozenClock implements Clock
{
private DateTimeImmutable $date;
public function __construct(DateTimeImmutable $date)
{
$this->date = $date;
}
public function now(): DateTimeImmutable
{
return $this->date;
}
}
SystemClock - implementation of service that rely on system clock
<?php
declare(strict_types=1);
namespace Xthiago;
use DateTimeImmutable;
class SystemClock implements Clock
{
public function now() : DateTimeImmutable
{
return new DateTimeImmutable();
}
}
Using it:
$birthDate = new BirthDate(new DateTimeImmutable('1988-96-14'));
$clock = new SystemClock();
$birthDate->age($clock)
Writting unit tests:
// ..
$birthDate = new BirthDate(new DateTimeImmutable('1988-96-14'));
$clock = new FrozenClock(new DateTimeImmutable('2019-07-16'));
$birthDate->age($clock)
Um possível approach pra facilitar seus testes é:
Uso:
Nos testes você pode usar instâncias de
DateTimeImmutable
pra datas e idades conhecidas. Acho mais simples mas, talvez não seja o que você precisa 😅