【问题标题】:How to fake DateTime in a phpunit test?如何在 phpunit 测试中伪造 DateTime?
【发布时间】:2019-06-26 05:08:44
【问题描述】:

ss我使用 Symfony 的 KernelTestCase 编写了一个单元测试,并且必须测试一个功能,这仅在一天中的某个时间(特别早或特别晚)发生。

所以当我让我的测试运行一个中午时,当然什么也没有发生。如何伪造我的系统时间来假装它有不同的时间并且我的测试用例被触发了。

我尝试了 Symfony 的 ClockMock 类,但它不起作用。 https://symfony.com/doc/current/components/phpunit_bridge.html#clock-mocking

这是我的测试代码:

use Symfony\Bridge\PhpUnit\ClockMock;
use \DateTime;

/**
 * testUserAchievedEarlyBirdTrophy
 * @group time-sensitive
 */
public function testUserAchievedEarlyBirdTrophy()
{
    ClockMock::withClockMock(strtotime('2018-11-05 01:00:00'));
    echo (new DateTime())->format('Y-m-d H:m:s');

    $user8Id = $this->user8->getId();
    $progressSaveRequest = new ProgressSaveRequest($user8Id, $this->content_1_1->getId());

    $this->progressService->saveProgress($progressSaveRequest);

    $this->assertTrue($this->loggerCreator->hasDebugThatContains(
        'Early Bird'
    ));
}

回声给我今天的日期:2019-02-01 16:02:06

我也觉得 ClockMock 更习惯于跳过时间,例如测试缓存而不是 sleep()。

我做错了什么?

监听器配置在我的 phpunit.xml 中 调用 bin/simple-phpunit 会导致大量安装发生。

不能用普通的phpunit吗?

还有其他方法可以伪造一天中的时间吗?

【问题讨论】:

    标签: phpunit symfony4 php-7.2


    【解决方案1】:

    按照您在帖子中包含的链接,第一段说:

    此桥提供的 ClockMock 类允许您模拟 PHP 的内置时间函数 time()、microtime()、sleep() 和 睡眠()。此外,函数 date() 被模拟,因此它使用 如果未指定时间戳,则为模拟时间。 其他功能 默认为 time() 的可选时间戳参数仍将使用 系统时间而不是模拟时间。 (已添加重点。)

    这意味着你的调用

    echo (new DateTime())->format('Y-m-d H:m:s');
    

    预计给系统时间,而不是模拟时间。

    改成

    echo date('Y-m-d H:m:s');
    

    为了匹配ClockMock的要求,得到模拟的时间。

    注意:我自己从未使用过 ClockMock,但只是查看文档,这应该是第一步,看看这是否能解决您的问题。

    【讨论】:

    • 太棒了!这就是我需要的提示。我现在使用要测试的方法的构造函数中的 date() 方法初始化我的 DateTime 对象,它可以工作! $myDate = (new DateTime(date('Y-m-d H:m:s')));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 2019-06-11
    相关资源
    最近更新 更多