通俗学习Mockito结合Spring跨多层接口mock测试方法

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

通俗学习Mockito结合Spring跨多层接口mock测试方法

1、场景:A调B,B调C,测试A,mock掉C

想要测试ServiceA服务的getUserVo()方法,而getUserVo()方法调用了ServiceB服务,ServiceB又调用了ServiceC服务的getUser()方法,需要mock掉ServiceC的getUser()方法。

2、操作方法: 详细如代码,参照代码注释

  1. 把需要mock注入的服务ServiceA,ServiceB加上@InjectMocks
  2. 把需要mock的服务ServiceC加上@Mock@Spy
  3. 执行测试方法前@Before初始化Mock注入,加上MockitoAnnotations.initMocks(this);
  4. 调用测试接口前执行需要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、扩展:

  1. @Mock@Spy的区别:

    • @Mock如果不写形如when(...).thenReturn(...)的打桩,服务下的所有属性方法将返回0或null;
    • @Spy不写when(...).thenReturn(...)打桩则是按真实的代码执行。
  2. when(...).thenReturn(...)doReturn(..).when(...)的区别:

    • 两者都返回mock结果,前者会调用真实代码后返回mock结果,后者直接返回mock结果。
    • 用法区别:when(serviceA.getUser(anyInt())).thenReturn(user)doReturn(user).when(serviceA).getUser(anyInt())
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值