【问题标题】:doAnswer in mockito - when is it lazy evaluation and when is it eager?doAnswer in mockito - 什么时候是懒惰的评估,什么时候是渴望的?
【发布时间】:2014-10-02 09:21:05
【问题描述】:

我在这段代码中使用了 mockito spy:

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);

当结构为时,我看到 answer() 被急切地调用:

when(spy.method())./*...*/.

但是当结构为时它是惰性求值:

/*...*/.when(spy).method()

不应该反过来吗?意思是/*...*/.when(spy).method() 是急切的,而when(spy.method())./*...*/. 是懒惰的?喜欢do..while loop 吗?

我找不到相关文档

【问题讨论】:

    标签: java unit-testing mockito lazy-evaluation


    【解决方案1】:

    关于这种语法你应该注意的一点:

    when(spy.method()).thenAnswer(someAnswer);
    

    Java 在评估它时要做的第一件事是运行吗:

         spy.method()
    

    ...以便它可以将准确的返回值传递给when 方法。当然,when 丢弃了它的参数,只是读取了对模拟的最后一次调用,但是 Java 无法从语法中知道这一点。对于第一次在模拟上调用when,该方法应该没有异常或副作用,但这种假设不适用于间谍或您已经存根的方法


    一般来说,doAnswer 和其他 doVerb 方法有两个关键用途:存根 void 方法覆盖已定义的行为(即,用于间谍和已经-存根方法)。

    无效方法

    // 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!" 中描述了后一种情况。

    【讨论】:

      【解决方案2】:

      我相信间谍的/*...*/.when(spy).method() 语法是 Mockito 的实现细节。如果您考虑一下,当您不想调用真实方法时,如何在此调用when(spy.method())./*...*/ 中实现 Mockito 功能以对 spy 的方法存根?您需要为间谍提供不同的 API,因为用于模拟的 API 不适合。

      这里是相关文档(请参阅“间谍真实对象的重要陷阱!”部分):https://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#13

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-17
        • 2015-09-06
        • 2016-12-18
        • 2014-12-02
        • 2020-10-01
        • 1970-01-01
        相关资源
        最近更新 更多