我有一个生成时间戳的模型构造函数 this.timestamp = null == timestamp ? ZonedDateTime.now().toInstant().toEpochMilli() : timestamp; 如何模拟ZoneDateTime?我需要使用测试用例验证时间戳的值是以毫秒为单位的当前时间。因为它是一个模型,所以注入一个独立的 clock 类在构造函数中是不可能的,我不希望更改源代码。
this.timestamp = null == timestamp ? ZonedDateTime.now().toInstant().toEpochMilli() : timestamp;
clock
kkih6yb81#
这取决于你的班级和你想做什么:如果您想模拟一个类的所有属性,而该类不是final,那么可以使用mockito这样的模拟框架。
MyClass mocked = Mockito.mock(MyClass.class); Mockito.when(mocked.getTimestamp()).thenReturn(**/ your value**/ )
如果类是final,则只需模拟此单个属性,否则属性就是final:您可以创建一个静态工厂,它为您提供 Instant 然后在你的测试中更换工厂。
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,它可以在您的测试中使用。下一个解决方案(不推荐)是使用反射。但这不是嘲弄,这是使用强制设置私有(事件最终)属性。还有一种方法可以覆盖测试的时钟
1条答案
按热度按时间kkih6yb81#
这取决于你的班级和你想做什么:
如果您想模拟一个类的所有属性,而该类不是final,那么可以使用mockito这样的模拟框架。
如果类是final,则只需模拟此单个属性,否则属性就是final:
您可以创建一个静态工厂,它为您提供
Instant
然后在你的测试中更换工厂。在构造器中:
现在在您的测试中,您可以使用setter方法:
只需记住在测试后返回默认供应商:
如果您的属性不是final,那么添加一个包setter,它可以在您的测试中使用。
下一个解决方案(不推荐)是使用反射。但这不是嘲弄,这是使用强制设置私有(事件最终)属性。
还有一种方法可以覆盖测试的时钟