通俗学习Mockito结合Spring跨多层接口mock测试方法
1、场景:A调B,B调C,测试A,mock掉C
想要测试ServiceA服务的getUserVo()方法,而getUserVo()方法调用了ServiceB服务,ServiceB又调用了ServiceC服务的getUser()方法,需要mock掉ServiceC的getUser()方法。
2、操作方法: 详细如代码,参照代码注释
- 把需要mock注入的服务ServiceA,ServiceB加上
@InjectMocks - 把需要mock的服务ServiceC加上
@Mock或@Spy - 执行测试方法前
@Before初始化Mock注入,加上MockitoAnnotations.initMocks(this); - 调用测试接口前执行需要mock的方法,指定mock的返回值
when(serviceC.getUser(anyInt())).thenReturn(user);
//手动导入static的Mockito包
import static org.mockito.Mockito.*;
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/spring-config.xml")
public class MockTest {
//需要mock注入的服务
@InjectMocks
@Autowired
private ServiceA serviceA;
//需要mock注入的服务
@InjectMocks
@Autowired
private ServiceB serviceB;
//需要mock掉的服务
@Mock
@Autowired
private ServiceC serviceC;
//初始化mock注入
@Before
public void initMock() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
User user = new User();
user.setId(1);
user.setName("张三");
//指定当调用ServiceC.getUser()时返回的user对象
when(serviceC.getUser(anyInt())).thenReturn(user);
/*
* serviceA -> serviceB -> serviceC
* 这里serviceA.getUserVo()里调用serviceB.getUserDto()方法,
* serviceB里又调用serviceC.getUser()方法,mock掉serviceC的getUser()方法
*/
UserVo userVo = serviceA.getUserVo("123");
log.info(JSONObject.toJSONString(userVo)); // UserVo(1, "张三")
}
}
3、扩展:
-
@Mock与@Spy的区别:@Mock如果不写形如when(...).thenReturn(...)的打桩,服务下的所有属性方法将返回0或null;- 而
@Spy不写when(...).thenReturn(...)打桩则是按真实的代码执行。
-
when(...).thenReturn(...)与doReturn(..).when(...)的区别:- 两者都返回mock结果,前者会调用真实代码后返回mock结果,后者直接返回mock结果。
- 用法区别:
when(serviceA.getUser(anyInt())).thenReturn(user)、doReturn(user).when(serviceA).getUser(anyInt())。

本文介绍如何使用Mockito与Spring进行多层接口的模拟测试。通过一个具体的场景——测试ServiceA的getUserVo()方法,该方法依赖于ServiceB,而ServiceB依赖于ServiceC的getUser()方法。通过Mockito,我们可以mock ServiceC,确保在测试中不实际调用到getUser()。详细步骤包括:添加mock服务,初始化Mock注入,设置mock返回值。还讨论了`@MockBean`与`@SpyBean`,以及`when(...).thenReturn(...)`与`doReturn(...).when(...)`的使用区别。

4341

被折叠的 条评论
为什么被折叠?



