我有以下单元测试:
@Test
public void testGenerateFileName(){
GregorianCalendar mockCalendar = Mockito.mock(GregorianCalendar.class);
Date date = new Date(1000);
Mockito.when(mockCalendar.getTime()).thenReturn(date);
...
}
在第三行,我收到以下错误:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue: Date cannot be returned by getTimeInMillis() getTimeInMillis() should return long
*** If you're unsure why you're getting above error read on. Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests. Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
为什么会这样?我没有使用getTimeInMillis()
。
答案 0 :(得分:3)
问题是方法GregorianCalendar.getTime()
是最终的,所以Mockito无法拦截方法调用。
另一种方法是使用Apache commons lang将日期转换为Calendar
,因此当您调用getTime
时,它会返回您期望的值
DateUtils.toCalendar(date)
如果你想疯狂,你可以使用PowerMock来模拟最终字段,但是当你有一个更简单的选择时,我认为不值得添加PowerMock的复杂性。
另一点。您应该尽量避免模拟您不拥有的对象,这对于单元测试和模拟对象来说非常重要。这是一个reference,它有一些关于这种做法的链接。
最后,因为它可能适用于您的项目:从您可以获取当前时间的位置引入“时钟”对象是一个很好的做法,测试可以操纵此时钟以返回“静态”当前时间。
Java 8包含Clock抽象,它具有适合测试的具体实现,可以通过调用Clock.fixed()
,Clock.tick()
,Clock.tickSeconds()
和Clock.tickMinutes()
来获取...或者您可以编写自己的Clock实现。