使用Mockito时,嘲笑和间谍有什么区别?
使用Mockito间谍的用例是什么?
在我看来,每个间谍用例都可以使用callRealMethod用模拟来处理。
我可以看到的一个区别是,如果您希望大多数方法调用都是真实的,它会保存一些代码行以使用模拟与间谍。是它还是我错过了更大的图景?
使用Mockito间谍的用例是什么?
在我看来,每个间谍用例都可以使用callRealMethod用模拟来处理。
我可以看到的一个区别是,如果您希望大多数方法调用都是真实的,它会保存一些代码行以使用模拟与间谍。是它还是我错过了更大的图景?
间谍和模拟之间的区别
当 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从何而来呢?内部 real size() 方法称为 size() 未被模拟(或存根),因此我们可以说该条目已添加到真实对象中。
资料来源:http://www.baeldung.com/mockito-spy+自我笔记。
答案在文档中:
真实部分模拟(自 1.8.0 起)
最后,在邮件列表上进行许多内部辩论和讨论之后,Mockito增加了部分模拟支持。以前,我们将部分模拟视为代码气味。但是,我们发现了部分模拟的合法用例。
在1.8版本之前,spy()没有产生真正的部分模拟,这对一些用户来说是令人困惑的。阅读更多关于间谍:在这里或在javadoc for spy(Object)方法。
callRealMethod()
是在 之后引入的,但是为了确保向后兼容性,spy() 当然被留在那里。spy()
否则,你是对的:间谍的所有方法都是真实的,除非被存根。除非调用,否则 mock 的所有方法都是存根的。一般来说,我更喜欢使用 ,因为它不会强迫我使用成语而不是传统的成语。callRealMethod()
callRealMethod()
doXxx().when()
when().thenXxx()