简体   繁体   English

Mocking ZonedDateTime Java8

[英]Mocking ZonedDateTime Java8

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

How to mock ZonedDateTime?如何模拟 ZonedDateTime? I need to validate using the test case that the value of the timestamp is the current time in milliseconds.我需要使用测试用例验证时间戳的值是当前时间(以毫秒为单位)。

Since it is a model, injecting a dependency of a separate clock class is not possible in the constructor and I do not wish to change the source code.由于它是 model,因此无法在构造函数中注入单独clock class 的依赖项,我不希望更改源代码。

It depends on your class and what you want to do:这取决于您的 class 以及您想要做什么:

  1. If you want to mock all properties of a class, and the class is not final, then use a mocking framework like Mockito .如果要模拟 class 的所有属性,并且 class 不是最终的,则使用 mocking 框架,例如Z4D11432CA816EACB373333

     MyClass mocked = Mockito.mock(MyClass.class); Mockito.when(mocked.getTimestamp()).thenReturn(**/ your value **/ )
  2. If your class is final, you want to only mock this single property or then property is final:如果您的 class 是最终的,您只想模拟这个单一的属性,或者属性是最终的:

You can create a static factory, that provides you with Instant and then in your test replace the factory.您可以创建一个 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; } 
} 

And in your constructor:在你的构造函数中:

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

Now in your test, you can us the setter method:现在在您的测试中,您可以使用 setter 方法:

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

Just remember to return to default supplier after the test:只需记住在测试后返回默认供应商:

TimeFactory.setInstantSupplier(Instant::now);
  1. If your property is not final, then add a package setter, that can be used in your test.如果您的属性不是最终的,那么添加一个 package 设置器,可以在您的测试中使用。

  2. Next solution (not recommended though) is to use reflection .下一个解决方案(虽然不推荐)是使用反射 But this is not mocking, this is using force to set a private (event final) properties.但这不是 mocking,这是使用强制设置私有(事件最终)属性。

  3. There is also a way to overwrite the clock for tests还有一种方法可以覆盖测试时钟

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

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