代码之家  ›  专栏  ›  技术社区  ›  Calamity Jane

如何在phpunit测试中伪造日期时间?

  •  0
  • Calamity Jane  · 技术社区  · 6 年前

    ssi使用symfony的kerneltestcase编写一个单元测试,并且必须测试功能,这只在一天中的某个时间段发生(特别早或特别晚)。

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

    我试过和symfony一起上发条课,但没用。 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更常用于跳过时间,例如测试缓存而不是睡眠()。

    我做错什么了?

    侦听器配置已在my phpunit.xml中就位。 调用bin/simple phpunit会导致大量安装。

    我不能用普通的phpunit吗?

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Willem Renzema    6 年前

    在你的文章中包含的链接之后,第一段说:

    这个桥提供的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,但只要看一下文档,这应该是第一步,看看是否可以解决您的问题。