模拟ZoneDateTime java8

8ehkhllq  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(310)

我有一个生成时间戳的模型构造函数 this.timestamp = null == timestamp ? ZonedDateTime.now().toInstant().toEpochMilli() : timestamp; 如何模拟ZoneDateTime?我需要使用测试用例验证时间戳的值是以毫秒为单位的当前时间。
因为它是一个模型,所以注入一个独立的 clock 类在构造函数中是不可能的,我不希望更改源代码。

kkih6yb8

kkih6yb81#

这取决于你的班级和你想做什么:
如果您想模拟一个类的所有属性,而该类不是final,那么可以使用mockito这样的模拟框架。

MyClass mocked = Mockito.mock(MyClass.class);       
Mockito.when(mocked.getTimestamp()).thenReturn(**/ your value**/ )

如果类是final,则只需模拟此单个属性,否则属性就是final:
您可以创建一个静态工厂,它为您提供 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);

如果您的属性不是final,那么添加一个包setter,它可以在您的测试中使用。
下一个解决方案(不推荐)是使用反射。但这不是嘲弄,这是使用强制设置私有(事件最终)属性。
还有一种方法可以覆盖测试的时钟

相关问题