mockito when - 然后返回错误

时间:2014-04-04 12:03:28

标签: unit-testing junit mockito

我有以下单元测试:

@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()

1 个答案:

答案 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实现。