我使用mockito间谍使用此代码:
Mockito.doAnswer(new Answer() {
Object answer(InvocationOnMock invocation) {
ImagesSorter mock = (ImagesSorter) invocation.getMock();
Object[] args = invocation.getArguments();
return mock.sortImages((List<Image>) args[0], (UserInfo) args[1],
fakeNowDate);
}
}).when(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);
我看到当结构为:
时,急切地调用了答案() when(spy.method())./*...*/.
但是当结构为:
时,它是懒惰的评估 /*...*/.when(spy).method()
不应该相反吗?意味着/*...*/.when(spy).method()
渴望而when(spy.method())./*...*/.
是懒惰的?像do..while loop
一样?
我找不到那份文件
答案 0 :(得分:3)
您应该注意一下这种语法:
when(spy.method()).thenAnswer(someAnswer);
这是Java在评估它时要做的第一件事:
spy.method()
...以便它可以将准确的返回值传递给when
方法。当然,when
会丢弃其参数,只读取对mock的最后一次调用,但Java无法从语法中知道。对于第一次在模拟上调用when
,该方法应该没有例外或副作用,但该假设不适用于间谍或您已经存根的方法
通常,doAnswer
和其他doVerb
方法有两个主要用途: stubbing void methods 和覆盖已经定义的行为(即间谍和已经存根的方法)。
无效方法
// Doesn't work: voidMethod has no return value, so when() has no parameter
when(yourMock.voidMethod()).thenThrow(new RuntimeException());
// This works, because it skips reading the voidMethod return value:
doThrow(new RuntimeException()).when(yourMock).voidMethod();
已经存根的方法
// Doesn't work: This contains a call to dangerousMethod!
when(yourSpy.dangerousMethod()).thenReturn(safeValue);
// This works, because the call to dangerousMethod happens on a dummy copy of yourSpy:
doReturn(safeValue).when(yourSpy).dangerousMethod();
正如lkrnac's answer中所述,Mockito在顶级Mockito文档中的"important gotcha on spying real objects!"中描述了后一种情况。
答案 1 :(得分:0)
我相信间谍的/*...*/.when(spy).method()
语法是Mockito实现细节。如果你考虑一下,当你不想调用真正的方法时,你如何在这个调用when(spy.method())./*...*/
中实现Mockito功能到间谍方法?您需要为间谍提供不同的API,因为用于模拟的API不合适。
以下是相关文档(请参阅“窥探真实物体的重要问题!”一节):https://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#13