carpiftw/clock-mock

这是一个用于测试中模拟当前日期和时间的库。

0.3.0 2021-09-15 10:36 UTC

This package is not auto-updated.

Last update: 2024-09-12 23:26:51 UTC


README

Slope s.r.l.

Latest Stable Version Total Downloads License

ClockMock提供了一种模拟PHP中用于DateTime(Immutable)对象和与日期/时间相关的函数的当前时间戳的方法。它需要uopz扩展(版本>= 6.1.1)。

此库仅用于开发和测试。它并不旨在提供一个用于生产代码的时钟服务,因为我们认为在测试代码中模拟当前时间时,您不应该需要这样做。

我们为什么要构建它

  • 我们正在寻找一种方法来模拟原生php日期和时间函数和类,而无需更改我们的生产代码,也无需使用任何第三方库来处理日期/时钟。
  • 为此,我们之前使用的是php-timecop扩展。问题是该扩展从未实现对PHP 7.4以上的支持。该扩展目前甚至无法为PHP 8.0构建。

安装

您可以使用Composer安装此库。运行以下命令从Packagist安装最新版本:

composer require --dev slope-it/clock-mock

请注意,由于这不是一个用于生产的工具,因此它仅应在开发中使用(--dev标志)。

模拟的函数/方法

  • date()
  • date_create()
  • date_create_immutable()
  • getdate()
  • gmdate()
  • idate()
  • localtime()
  • microtime()
  • strtotime()
  • time()
  • DateTime::__construct
  • DateTimeImmutable::__construct

缺少模拟的函数/方法(需要帮助!)

  • date_create_from_format()
  • date_create_immutable_from_format()
  • gettimeofday()
  • gmmktime()
  • gmstrftime()
  • mktime()
  • strftime()
  • unixtojd()
  • DateTime::createFromFormat
  • DateTimeImmutable::createFromFormat
  • $_SERVER['REQUEST_TIME']

使用方法

1. 有状态的API

您可以通过传递\DateTime或\DateTimeImmutable来调用ClockMock::freeze。在此之后执行的任何代码都将使用该特定日期和时间作为当前时间戳。完成后调用ClockMock::reset以恢复真实、当前的时钟。

示例

<?php

use PHPUnit\Framework\TestCase;
use SlopeIt\ClockMock\ClockMock;

class MyTestCase extends TestCase
{
    public function test_something_using_stateful_mocking_api()
    {
        ClockMock::freeze(new \DateTime('1986-06-05'));
        
        // Code executed in here, until ::reset is called, will use the above date and time as "current"
        $nowYmd = date('Y-m-d');
        
        ClockMock::reset();
        
        $this->assertEquals('1986-06-05', $nowYmd);
    }
}

2. 无状态的API

此库还提供基于闭包的API,该API将在特定时间点执行提供的代码。此API不需要手动冻结或重置时间,因此在某些情况下可以减少错误。

示例

<?php

use PHPUnit\Framework\TestCase;
use SlopeIt\ClockMock\ClockMock;

class MyTestCase extends TestCase
{
    public function test_something_using_stateless_mocking_api()
    {
        $nowYmd = ClockMock::executeAtFrozenDateTime(new \DateTime('1986-06-05'), function () {
            // Code executed in here will use the above date and time as "current"
            return date('Y-m-d');
        });
        
        $this->assertEquals('1986-06-05', $nowYmd);
    }
}

如何贡献

  • 您是否在现有代码中找到了并修复了任何错误?
  • 您想贡献一个新功能或缺失的模拟吗?
  • 您认为文档可以改进吗?

在任何这些情况下,请将此存储库分支并创建一个拉取请求。我们非常乐意接受贡献!

致谢

  • php-timecop,因为ClockMock受到了它的启发。
  • ext-uopz,因为ClockMock只是建立在功能强大的uopz扩展之上的一个非常薄的层,该扩展提供了一种在运行时模拟任何函数或方法,包括php stdlib中的函数或方法,的非常方便的方式。

维护者

@andreasprega