mock和spy都是test double(测试替身)的其中一种,我们都可以对其进行stub,但是他们两个使用场景却截然不同。
我们先来看一段代码(测试方法都是可以通过的):
@ExtendWith(MockitoExtension.class)
public class MockSpyTest {
@Mock
private List<String> mockList;
@Spy
private List<String> spyList = new ArrayList<>();
@Test
public void testSpyList() {
// 调用真实对象的add方法
spyList.add("abc"); // 1
assertEquals(1, spyList.size());
// stub
when(spyList.size()).thenReturn(10);
// 校验size是否为
assertEquals(10, spyList.size());
}
@Test
public void testMockList() {
// 调用mock对象的add方法
mockList.add("abc"); // 2
assertEquals(0, mockList.size());
// stub
when(mockList.size()).thenReturn(10);
assertEquals(10, mockList.size());
}
}
- 当我们调用
spyList#add
的时候,add的方法是被真实调用了,因此spyList的size是1 - 当我们调用
mockList#add
的时候,add的方法并没有被真实调用,因此spyList的size是0
无论是spy还是mock出的对象,stub的效果都是一致的,list集合size都是我们想要的10。
那什么时候应该用spy,什么时候应该用mock呢?
- 不想调用真实的方法,只是想对其行为进行stub。例如发送邮件给客户,这种场景下我们并不想真的发送邮件给客户,这个时候应该使用mock。
- 想调用真实的方法,并且执行一些代码逻辑,然后观测其行为,这个时候我们应该使用spy。例如邮件发送人为自己,然后对发送邮件之外的方法进行stub,观测我们程序的行为并进行verify。
Reference