使用 Mockito 时,模拟和间谍有什么区别?

新手上路,请多包涵

使用 Mockito 间谍的用例是什么?

在我看来,每个间谍用例都可以使用 callRealMethod 模拟处理。

我可以看到的一个区别是,如果您希望大多数方法调用是真实的,它可以节省一些代码行来使用模拟与间谍。是这样还是我错过了更大的图景?

原文由 Victor Grazi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 553
2 个回答

答案在 文档 中:

真正的部分模拟(自 1.8.0 起)

最后,在邮件列表上进行了多次内部辩论和讨论后,部分模拟支持被添加到 Mockito。以前我们将部分模拟视为代码异味。但是,我们发现了部分模拟的合法用例。

在 1.8 版本之前,spy() 没有产生真正的部分模拟,这让一些用户感到困惑。阅读有关间谍的更多信息: 此处 或在 javadoc 中用于 spy(Object) 方法。

callRealMethod() 是在 spy() 之后引入的,但是 spy() 当然被留在那里,以确保向后兼容性。

否则,你是对的:间谍的所有方法都是真实的,除非被存根。除非调用 callRealMethod() ,否则模拟的所有方法都会被存根。一般来说,我更喜欢使用 callRealMethod() ,因为它不会强迫我使用 doXxx().when() 成语而不是传统的 when().thenXxx()

原文由 JB Nizet 发布,翻译遵循 CC BY-SA 4.0 许可协议

间谍和模拟之间的区别

当 Mockito 创建一个模拟时——它是从一个类型的类中创建的,而不是从一个实际的实例中创建的。模拟只是创建了类的一个基本的 shell 实例,完全用于跟踪与它的交互。另一方面,间谍将包装现有实例。它仍将以与普通实例相同的方式运行——唯一的区别是它还将被检测以跟踪与其进行的所有交互。

在下面的例子中——我们创建了一个 ArrayList 类的模拟:

 @Test
public void whenCreateMock_thenCreated() {
    List mockedList = Mockito.mock(ArrayList.class);

    mockedList.add("one");
    Mockito.verify(mockedList).add("one");

    assertEquals(0, mockedList.size());
}

如您所见——将元素添加到模拟列表中实际上并没有添加任何东西——它只是调用了没有其他副作用的方法。另一方面,间谍的行为会有所不同——它实际上会调用 add 方法的实际实现并将元素添加到基础列表中:

 @Test
public void whenCreateSpy_thenCreate() {
    List spyList = Mockito.spy(new ArrayList());
    spyList.add("one");
    Mockito.verify(spyList).add("one");

    assertEquals(1, spyList.size());
}

在这里我们可以肯定地说调用了对象的真正内部方法,因为当您调用 size() 方法时,您得到的大小为 1,但是这个 size() 方法并没有被模拟! 那么1从何而来? 调用内部真实 size() 方法是因为 size() 未被模拟(或存根),因此我们可以说该条目已添加到真实对象中。

资料来源: http ://www.baeldung.com/mockito-spy + 自我笔记。

原文由 Saurabh Patil 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题