我的一种方法中有以下代码-
ZonedDateTime current = Instant.now().atZone(ZoneId.of(AMERICA_NEW_YORK));
我想在junit测试中模拟current
。
我尝试使用java.time.Clock
,但是为此我需要将其添加到类构造函数中,因为我的代码被写入到Spring的旧版本中,并且使用基于xml的配置,该类会引起问题,因为它需要在应用程序上下文中使用构造函数参数.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());
答案 0 :(得分:2)
您可以声明一个返回ZoneDateTime
的函数:
public ZoneDateTime getCurrentTime () {
return Instant.now().atZone(ZoneId.of(AMERICA_NEW_YORK));
}
并将该函数的结果分配给current
字段:
ZonedDateTime current = getCurrentTime();
现在,您可以使用Mockito framework将其替换为所需的值:
doReturn(yourValue).when(yourObject).getCurrentTime();
答案 1 :(得分:1)
使用 Mockito 时,您可以像这样轻松模拟:
ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime current = ZonedDateTime.now(zoneId);
Timestamp timestamp = Timestamp.from(Instant.now());
when(timestamp.toInstant()).thenReturn(Instant.from(current));
添加超时测试示例:
@Test
public void testForTimeout() throws InterruptedException {
ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime current = ZonedDateTime.now(zoneId);
Timestamp timestampBeforeCall = Timestamp.from(Instant.now());
// Call Class.method() or here instead we just introduce an artificial wait time :
Thread.sleep(3000);
Timestamp timestampAfterCall = Timestamp.from(Instant.now());
long timeoutInMilliseconds = 2000;
long diff = timestampAfterCall.getTime() - timestampBeforeCall.getTime();
log.info(String.valueOf(diff));
if(diff > timeoutInMilliseconds) {
log.error("Call Timed Out!");
}
}