This library is not production ready yet, and can be subject to heavy changes.
Simple DateTime
provider. Allows time freezing for testing purposes.
You can install this library:
- Install via composer:
composer require shopery/datetime
- Use the official Git repository:
git clone https://github.com/shopery/datetime
.
Replace every new DateTime()
with a call to Shopery\DateTime\DateTime::now()
for better testability.
To create relative datetimes, be it in the past or the future, use Shopery\DateTime\DateTime::create($timeString)
passing a GNU string modificator.
You can freeze time with the static method DateTime::freeze()
. Pass any date as argument to set the current frozen time. This allows testing time-dependent scenarios.
You should remember to call DateTime::unfreeze
at the end of the tests to clear it.
use Shopery\DateTime\DateTime;
use DateTime as NativeDateTime;
class Coupon
{
private $expiredTime;
public function __construct(NativeDateTime $expiredTime)
{
$this->expiredTime = $expiredTime;
}
public function hasExpired()
{
return DateTime::now() > $this->expiredTime;
}
}
class CouponTest
{
public function test_has_expired()
{
$coupon = new Coupon(DateTime::create('yesterday'));
$this->assertTrue($coupon->hasExpired());
$frozenTime = DateTime::create('a month ago');
DateTime::freeze($frozenTime);
$this->assertFalse($coupon->hasExpired());
DateTime::unfreeze();
}
}
You can setup PHPUnit to freeze time while entering some of your tests.
A PHPUnit listener is provided which adds a freezeTime
annotation for your tests.
Here are the changes you need to do to your phpunit.xml
:
<phpunit>
...
<listeners>
<listener class="Shopery\DateTime\Listener\PHPUnit\DateTimeListener" />
</listeners>
...
</phpunit>
And now, you can add @freezeTime
in the PHPDoc of each test.
class MyTest
{
/**
* @freezeTime
*/
public function test_frozen_in_current_time()
{
}
/**
* @freezeTime 2015-01-31 08:30:00
*/
public function test_frozen_in_a_given_date()
{
}
/**
* @freezeTime first monday of January last year
*/
public function test_frozen_in_a_relative_date()
{
}
public function test_this_is_not_frozen()
{
}
}