在mockito做的答案 - 什么时候是懒惰的评价,什么时候急切?

时间:2014-10-02 09:21:06

标签: java unit-testing mockito lazy-evaluation

我使用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一样?

我找不到那份文件

2 个答案:

答案 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