繁体   English   中英

如何使用mockito间谍进行懒惰评估?

[英]how to use mockito spy for lazy evaluation?

我想用mockito间谍。

当我以下列两种方式设置返回值时:

when(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user)).thenReturn(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user, fakeNowDate));

doReturn(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user, fakeNowDate)).when(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);

我看到正在急切地评估返回值

执行此“设置”行时的含义。

我如何强迫间谍只根据需要评估回报价值?

表示满足“when”条件时的含义。

更新

感谢@RobbyCornelissen我试过这段代码:

    when(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user)).thenAnswer(new Answer() {
        public Object answer(InvocationOnMock invocation) {
            Object[] args = invocation.getArguments();
            ImagesSorter mock = (ImagesSorter)invocation.getMock();
            return mock.sortImages((List<Image>)args[0], (UserInfo)args[1], fakeNowDate);
        }
    });

但它没有帮助:

1)立即调用“when”表达式。 (不想要的)

2)最终回调不是调用。

首先让我对部分嘲讽发出警告,因为这就是代码实际上正在做的事情,这是错误的设计明智。 使用策略模式来组成测试对象的行为可能更相关。 Mockito团队(包括我)强烈建议尽可能远离部分嘲笑。

编辑 :我不知道代码,我ImagesSorter知道哪个组件正在测试,但从我收集的是一个负责排序图像的类型,让我们称之为ImagesSorter

  1. 因此,第一种情况ImagesSorter是测试主题的依赖关系,所以在这种情况下,只需ImagesSorter 模拟 ImagesSorter

  2. 但是,如果它是ImagesSorter本身正在测试中,并且对该类的特殊方法进行存根称为部分模拟,则它是完全错误的。 它公开了测试中生产代码的内部。 所以有几种解决方案。

    1. 正如答案中显示的代码片段显示的是fakeDate ,其中一个解决方案是不使用new Date()等代码并编写一个简单的类TimeSource其唯一的责任是提供日期。 在测试中,这个TimeSOurce可以被覆盖。

      一个更简单的解决方案是使用JodaTime,因为它提供了内置的这个功能。

    2. 如果测试范围超出了更改日期的范围,那么ImagesSorter可能需要一种配置其他对象的方法。 可以通过番石榴的缓存构建器找到有关如何执行此操作的灵感。 如果配置很简单,那么一个简单的构造函数就可以做到。

      这可能看起来像:

       class ImagesSorter { ImagesSorterAlso algo; ImagesSorter(ImagesSorterAlgo algo) { this.algo = algo; } Iterable sortImages(...) { algo.sort(...); } } interface ImagesSorterAlgo { Iterable sort(...); } 

现在关于你的问题:

1)立即调用“when”表达式。 (不想要的)

预计imagesSorterSpy是间谍,所以默认情况下它会调用真实代码。 相反,您应该使用备用API,与@RobbyCornelissen显示的相同。

doAnswer(sortWithFakeDate()).when(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);

// with BDD aliases (BDDMockito) which I personnaly finds better
willAnswer(sortWithFakeDate()).given(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);
will(sortWithFakeDate()).given(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);

sortWithFakeDate()将返回一个返回答案的静态工厂方法,因此代码读取得很好,并且可能在其他地方重用。

2)最终回调不是调用。

这个问题很可能是由于不相等的论点造成的。 您可能需要检查equals方法。 或者使用any()匹配器放松存根。

我不知道您正在使用的参数和类的类型,因此我无法提供完整的示例,但您可以使用Answer<T>接口使用回调来存根:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM