我正在尝试模拟静态方法Instant.now()
,并且在尝试从包中模拟类时继续遇到奇怪的行为java.time
。请参阅下面我关于尝试模拟Instant.now()
的代码
@RunWith(PowerMockRunner.class)
@PrepareForTest(Instant.class)
public class UnitTestClasss {
@Test
public void unitTestMethod() throws Exception {
mockCurrentTimeAtMidNight();
instanceOfSystemUnderTest.someMethodDependingOnTime();
assertHandledHere();
}
/*See First Error Below */
private void mockCurrentTimeAtMidNight() {
ZonedDateTime current = ZonedDateTime.now();
ZonedDateTime mockMidNight = ZonedDateTime.of(current.getYear(), current.getMonthValue(),
current.getDayOfMonth(), 0, 0, 0, 0,current.getZone());
PowerMockito.mockStatic(Instant.class);
PowerMockito.when(Instant.now()).thenReturn(Instant.from(mockMidNight));
}
/*See Second Error Below */
private void mockCurrentTimeAtMidNight2() {
Calendar cal = Calendar.getInstance();
ZonedDateTime mockMidNight = ZonedDateTime.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0, 0,ZoneId.of("US/Eastern"));
Instant instant = mockMidNight.toInstant();
PowerMockito.mockStatic(Instant.class);
PowerMockito.when(Instant.now()).thenReturn(instant);
}
}
错误 1 org.mockito.exceptions.misusing.unfinishStubbingException: 此处检测到未完成的存根: -> at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:495)
错误E.g. thenReturn() may be missing. Examples of correct stubbing: when(mock.isOk()).thenReturn(true); when(mock.isOk()).thenThrow(exception); doThrow(exception).when(mock).someVoidMethod(); Hints: 1. missing thenReturn() 2. you are trying to stub a final method, you naughty developer! 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
2:原因:[源错误]
toInstant()
找不到java.time.ZonedDateTime
据我所知,我得到了错误,因为最初我在单元测试中调用 .now(),然后试图模拟它。这样做的原因是因为我认为我可以让我的测试使用该方法而不模拟,然后模拟它,这样我的 SUT 就可以使用模拟形式。
我最终改变了一点,并嘲笑ZonedDateTime.ofInstant(obj,obj)
。 这就是我所做的
@Test
public void renamingToArbitraryMethodName() throws Exception {
ZonedDateTime current = ZonedDateTime.now();
ZonedDateTime mockMidNight = ZonedDateTime.of(current.getYear(), current.getMonthValue(),
current.getDayOfMonth(), 0, 0, 0, 0, ZoneId.of("US/Eastern"));
PowerMockito.mockStatic(ZonedDateTime.class);
PowerMockito.when(ZonedDateTime.ofInstant(anyObject(), anyObject())).thenReturn(mockTime);
}
在我的场景中,这对我有用,因为我能够使用 .now()
摆脱我的测试类,而我的 SUT 源使用 .ofInstant(...)
.
你试图模拟一个java.time
类,这意味着你正在尝试模拟一个系统类。这要求您在@PrepareForTest注释中测试自己的系统,因为 PowerMock 无法拦截您正在调用的类的加载,因此它必须拦截您的类的加载并在那里进行字节码重写。
(这与您的错误消息并不完全匹配,但仍然是一个非常明确的原因,为什么您在这里遇到问题,而您在 Mockito 和 PowerMock 中的非系统类都不会遇到麻烦。
模拟系统类的危险 - 除了你正在模拟数据对象,特别是具有显式单元测试功能的对象(如评论中提到的时钟覆盖Andy Turner)之外 - 是在这里不使用模拟的一个很好的理由。