mcustiel/mockable-datetime

一个允许在单元测试中模拟日期和时间的 DateTime 库。

v2.0.0 2019-04-10 20:34 UTC

This package is auto-updated.

Last update: 2024-08-25 07:42:53 UTC


README

这是什么

Mockable DateTime 是一个用 PHP 编写的库,允许开发者在单元测试中模拟日期。有时需要验证某个操作是否以特定参数执行,其中一个参数是日期或时间(通常使用 date() 或 time() 内置函数获取),并且很难确保它在验证时具有特定的值。Mockable DateTime 通过让开发者以某种方式获取 PHP 的内置 DateTime 类来解决此问题,这样返回的值可以在单元测试中模拟,而无需将 DateTime 注入为依赖项。

Build Status Scrutinizer Code Quality Code Coverage

安装

Composer

{
    "require": {
        "mcustiel/mockable-datetime": "^2.0"
    }
}

如何使用它?

在您的代码中

每次需要获取系统日期时,请使用 Mockable DateTime

use Mcustiel\Mockable\DateTime;

// ...
function savePersonInfoInDatabase(Person $person)
{
    /** @var PersonDbEntity $person */
    $person = $this->converter->convert($person, PersonDbEntity::class);
    $person->setCreatedAt(DateTime::newPhpDateTime()); // DateTime::newImmutablePhpDateTime() can also be used
    $this->dbClient->insert($person);
}
// ...

还可以传递参数来创建 DateTime 对象

use Mcustiel\Mockable\DateTime;

// ...
function savePersonInfoInDatabase(Person $person)
{
    /** @var PersonDbEntity $person */
    $person = $this->converter->convert($person, PersonDbEntity::class);
    $person->setCreatedAt(DateTime::newPhpDateTime(
        '-4 months', 
        new \DateTimeZone('America/New_York')
    )); // DateTime::newImmutablePhpDateTime() can also be used
    $this->dbClient->insert($person);
}
// ...

如示例所示,我没有直接使用 PHP 的 \DateTime。相反,我使用 Mockable DateTime 来创建 PHP 的 \DateTime 的实例。

然后您必须测试它,并断言插入方法被调用,并带有一些特定的日期作为参数。对于示例,我将使用 PHPUnit。

use Mcustiel\Mockable\DateTime;

// ...

/**
 * @test
 */
function shouldCallInsertPersonWithCorrectData()
{
    DateTime::setFixed(new \DateTime('2000-01-01 00:00:01'));
    // Now every call to MockableDateTime::newPhpDateTime() will always return "2000-01-01 00:00:01"
    /** @var Person $person */
    $person = new Person('John', 'Doe');
    /** @var PersonDbEntity $expected */
    $expected = new PersonDbEntity('John', 'Doe');
    $expected->setCreatedAt(new \DateTime('2000-01-01 00:00:01'));    
    
    $this->dbClientMock->expects($this->once())
        ->method('insert')
        ->with($this->equalTo($expected));
    // ...and other needed mocks
    $this->unitUnderTest->savePersonInfoInDatabase($person);
}
// ...

就是这样。为了使其工作,代码和测试应在同一环境中执行(如果您再次在一个正在运行的 webservice 实例上执行测试,则不会工作),但对于单元测试和某些低级功能测试应该足够。

DateTime 方法

void setFixed(\DateTime $dateTime)

此方法使所有 Mockable DateTime 实例始终返回由 $dateTime 参数指定的日期和时间。

void setOffset(\DateTime $dateTime)

此方法使所有 Mockable DateTime 实例始终返回一个与指定日期时间偏移量相等的日期和时间。时间从调用此方法时开始。因此,如果您设置一个偏移量等于 '2005-05-05 01:00:00' 并休眠 5 秒,则对创建新的 \DateTime 的调用将返回一个设置为 '2005-05-05 01:00:05' 的日期。

void setSystem()

此方法使所有 Mockable DateTime 实例始终返回当前系统时间(默认行为)。

\DateTime newPhpDateTime($time = 'now', \DateTimeZone $timeZone = null)

根据 Mockable DateTime 的配置创建 PHP 的 \DateTime 类的新实例。

\DateTimeImmutable newImmutablePhpDateTime($time = 'now', \DateTimeZone $timeZone = null)

根据 Mockable DateTime 的配置创建 PHP 的 \DateTimeImmutable 类的新实例。