首页 > 解决方案 > 模拟 Instant.now() 而不在构造函数中使用时钟或没有时钟对象

问题描述

我的一种方法中有以下代码

ZonedDateTime current = Instant.now().atZone(ZoneId.of(AMERICA_NEW_YORK));

我想current在 JUnit 测试中进行模拟。

我试过了,java.time.Clock但为此,我需要将它添加到类构造函数中,因为我的代码被写入旧版本的 Spring 并使用基于 XML 的配置,这个类会导致问题,因为它需要 application-context.xml 文件中的构造函数参数,如果我将构造函数与Clock.

有什么办法可以避免current上面代码中的构造函数配置和模拟。

更新

根据 Pavel Smirnov 的评论,我在下面尝试过,但current仍然返回今天的日期,但不是我嘲笑的那个。

ZonedDateTime exactOneDay = ZonedDateTime.parse("Sun Oct 21 12:30:00 EDT  2018", Parser); 
doReturn(exactOneDay).when(spyEmployeeHelper).getCurrentTime();
employee = getEmployees().get(0);
assertEquals(Integer.valueOf(1), employee.getNoticePeriod());

标签: javajunitjava-8

解决方案


您可以声明一个返回的函数ZoneDateTime

public ZoneDateTime getCurrentTime () {
    return Instant.now().atZone(ZoneId.of(AMERICA_NEW_YORK));
}

并将该函数的结果分配给该current字段:

ZonedDateTime current = getCurrentTime();

现在您可以使用Mockito 框架简单地将其替换为所需的值:

doReturn(yourValue).when(yourObject).getCurrentTime();

推荐阅读