Jmockit使用笔记_增加代码覆盖率_覆盖try catch_使用new MockUp私有方法

覆盖catch,模拟new对象方法及私有方法处理

测试案例的Jmockit版本
<dependency>
    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.38</version>
    <scope>test</scope>
</dependency>
覆盖try catch中的异常处理逻辑
/**
 * 业务代码中进行了异常处理
 */
@Override
public void catchExceptionService() {
    try {
        List<String> queryResultList = myMapper.queryAllList();
    } catch (Exception e) {
        log.error("查询数据集合时发生异常:{}", e);
    }
}

测试案例模拟抛出异常,覆盖catch中的代码

/**
 * 测试案例
 */
@Test
public void catchExceptionService_test() {
    new Expectations() {
        {	
            // 让该方法被调用时抛出异常
            myMapper.queryAllList();
            result = new RuntimeException();
        }
    };
    myServicempl.catchExceptionService();
}
使用new MockUp模拟被测试代码中的私有方法
/**
 * @author: xinruoxiangyang9010
 * 业务代码:getOrderId()方法中调用了本类中的私有方法
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Override
    public String getOrderId() {
        List<String> orderIds = new ArrayList<>();
        orderIds.add("01");
        String productName = getProductName(orderIds);
        // 以下可能会用productName做一些其他的业务逻辑
        // .... ....
        return "OrderXX";
    }

    private String getProductName(List<String> orderIdList) {
        // 以下两行用于测试在mock时是否会调用真实代码逻辑
        orderIdList.add("readId1");
        orderIdList.add("readId2");
        // 返回结果
        return "Product01";
    }
}

对于单测案例来说,我们应该只关注 getOrderId()代码体中的内容,而避免受getProductName()方法的结果而影响测试案例结果,所以将getProductName()方法mock掉

/**
 * @author: xinruoxiangyang9010
 * 测试案例:被测试的方法:orderService.getOrderId()
 */
@RunWith(JMockit.class)
public class OrderServiceImplTest {

    @Tested
    private OrderServiceImpl orderService;

    @Test
    public void getOrderId() {
        new MockUp<OrderServiceImpl>() {
            @Mock
            private String getProductName(List<String> orderIdList){
                return "mock01";
            }
        };
        String orderId = orderService.getOrderId();
        Assert.assertEquals("OrderXX", orderId);
    }
}

可以通过断点模式看到,当方法getProductName()被调用时,直接按照我们Mock的结果进行返回,并没有进入到真实的方法中

使用 @Mocked对new的对象方法进行Mock
/**
 * 业务代码1
 * OrderCheck对象是new出来的,而不是注入的
 * @return
 */
@Override
public String getOrderName() {
    String orderName = "A000001";
    OrderCheck orderCheck = new OrderCheck();
    orderCheck.checkOrderName(orderName);
    return orderName;
}
/**
 * @author: xinruoxiangyang9010
 * 业务代码2
 * 以下的逻辑比较简单,但是如果遇到比较复杂的逻辑就不好调用真实方法了
 */
public class OrderCheck {
    public void checkOrderName(String orderName) {
        if (StringUtils.isEmpty(orderName) || !orderName.startsWith("B")) {
            throw new RuntimeException("订单名称校验异常");
        }
    }
}

与上面的案例类似, 当不想测试结果受checkOrderName(String orderName)方法影响时,将他Mock掉

/**
 * @author: xinruoxiangyang9010
 * 测试案例
 */
@RunWith(JMockit.class)
public class OrderServiceImplTest {
    @Mocked
    private OrderCheck orderCheck;
    @Tested
    private OrderServiceImpl orderService;

    @Test
    public void getOrderName_test(){
        new Expectations() {
            {
                orderCheck.checkOrderName(anyString);
                result = null;
            }
        };
        String orderName = orderService.getOrderName();
        Assert.assertEquals("A000001", orderName);
    }

}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值