通俗学习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())
。
版权声明:本文为fqfa1226原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。