繁体   English   中英

Mocking ZonedDateTime Java8

[英]Mocking ZonedDateTime Java8

我有一个 model 构造函数,它生成一个时间戳为this.timestamp = null == timestamp? ZonedDateTime.now().toInstant().toEpochMilli(): timestamp; this.timestamp = null == timestamp? ZonedDateTime.now().toInstant().toEpochMilli(): timestamp;

如何模拟 ZonedDateTime? 我需要使用测试用例验证时间戳的值是当前时间(以毫秒为单位)。

由于它是 model,因此无法在构造函数中注入单独clock class 的依赖项,我不希望更改源代码。

这取决于您的 class 以及您想要做什么:

  1. 如果要模拟 class 的所有属性,并且 class 不是最终的,则使用 mocking 框架,例如Z4D11432CA816EACB373333

     MyClass mocked = Mockito.mock(MyClass.class); Mockito.when(mocked.getTimestamp()).thenReturn(**/ your value **/ )
  2. 如果您的 class 是最终的,您只想模拟这个单一的属性,或者属性是最终的:

您可以创建一个 static 工厂,为您提供Instant ,然后在您的测试中替换工厂。

 class TimeFactory {

  private static Supplier<Instant>  INSTANT_SUPPLIER = Instant::now;
  public static Instant getInstant(){ return INSTANT_SUPPLIER.get(); }
  public static void setInstantSupplier(Supplier<Instant> new){ INSTANT_SUPPLIER= supplier; } 
} 

在你的构造函数中:

this.timestamp = null == timestamp ? TimeFactory.getInstant().toEpochMilli() : timestamp;

现在在您的测试中,您可以使用 setter 方法:

 TimeFactory.setInstantSupplier(()-> /*Your value*/ )
 // create your object

只需记住在测试后返回默认供应商:

TimeFactory.setInstantSupplier(Instant::now);
  1. 如果您的属性不是最终的,那么添加一个 package 设置器,可以在您的测试中使用。

  2. 下一个解决方案(虽然不推荐)是使用反射 但这不是 mocking,这是使用强制设置私有(事件最终)属性。

  3. 还有一种方法可以覆盖测试时钟

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM