如何在phpunit测试中伪造DateTime?

时间:2019-02-01 15:37:13

标签: phpunit symfony4 php-7.2

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吗?

还有其他选择来伪造一天中的时间吗?

1 个答案:

答案 0 :(得分:2)

在您包含在帖子中的链接之后,第一段显示:

  

此桥提供的ClockMock类可让您模拟   PHP的内置时间函数time(),microtime(),sleep()和   usleep()。此外,函数date()已被模拟,因此它使用了   如果未指定时间戳,则为模拟时间。 具有   默认为time()的可选timestamp参数仍将使用   系统时间而不是模拟时间。   (添加了强调。)

这意味着您致电

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

应该给系统时间,而不是模拟时间。

将其更改为

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

为了满足ClockMock的要求并获得模拟时间。

注意:我从来没有亲自使用过ClockMock,但只是查看文档,这应该是第一步,看看这是否可以解决您的问题。