JMockit初体验
一.Mock的使用场景:
比如以下场景:
1. mock掉外部依赖的应用的HSF service的调用,比如uic,tp 的hsf服务依赖。
2. 对DAO层(访问mysql、oracle、tair、tfs等底层存储)的调用mock等。
3. 对系统间异步交互notify消息的mock。
4. 对method_A里面调用到的method_B 的mock 。
5. 对一些应用里面自己的 class(abstract, final, static),interface,annotation ,enum,native等的mock。
二. Mock工具的原理:
1. record阶段:录制期望。也可以理解为数据准备阶段。创建依赖的class 或interface或method ,模拟返回的数据,及调用的次数等。
2. replay阶段:通过调用被测代码,执行测试。期间会invoke 到 第一阶段record的mock对象或方法。
3. verify阶段:验证。可以验证调用返回是否正确。及mock的方法调用次数,顺序等。
三. Mock的两种方式:
1. Behavior-oriented(Expectations & Verifications) ;
2. State-oriented(MockUp) 。
通俗点讲,Behavior-oriented是基于行为的mock,对mock目标代码的行为进行模仿,更像黑盒测试。State-oriented 是基于状态的mock,是站在目标测试代码内部的。可以对传入的参数进行检查、匹配,才返回某些结果,类似白盒。而State-oriented的 new MockUp基本上可以mock任何代码或逻辑。非常强大。
四. Mock使用的简单例子:
1. Behavior-oriented(Expectations & Verifications) 方式的简单运用
@RunWith(JMockit.class)
publicclassApplyServiceImplTest {
@Tested
privateApplyServiceImplapplyServiceImpl; //被测试的类
@Injectable
privateCustomerMappercustomerMapper; //测试函数使用到的外部类
@Test
publicvoidtestSendConfrimBorrowSms_Success() {
//开始录制期望数据
newExpectations() {
{
//指定要mock的函数,该函数为被测试函数中使用的用户数查询函数
customerMapper.selectByPrimaryKey(anyLong);
//指定mock函数需要返回的结果值
result= getCustomerVo();
}
};
//执行被测试函数逻辑
String applyNo ="10389278638798123";
Long userId = 500000975l;
intresutls =applyServiceImpl.sendConfrimBorrowSms(applyNo, userId);
//验证测试结果是否达到预期
assertEquals(1, resutls);
}
2. State-oriented(MockUp) 方式的简单运用
采用MockUp的方式,可以mock任意的mock对象或方法,因为它直接改写了原method的实现逻辑,直接返回需要的数据
@Test
publicvoidtestMethodA() {
//对CustomerManager的函数进行mock(被mock的类和函数需是被测试函数中被调用的类和函数)
newMockUp() {
@mockit.Mock
publicvoid$clinit() {
//1、如CustomerManager中有初始化的静态块时,$clinit不可缺省
//2、如果使用CustomerManager的带参构造函数,需使用jmockit的带参构造方式,如:
//publicvoid$init(String version) {
// 实现预期的操作,如果需要mock掉,不想做任何处理,这里空着就可以
//}
}
//指定要mock的函数(函数的声明要与CustomerManager中的保持一致)
@mockit.Mock
public Customer selectByPrimaryKey(Long id){
//修改CustomerManager类中的selectByPrimaryKey的实现逻辑,返回mock的期望值
Customer customer = new Customer();
customer.setName("王小贱");
returncustomer;
}
};
//执行被测试函数逻辑
String applyNo ="10389278638798123";
Long userId = 500000975l;
Customerresutls =applyServiceImpl.queryUserInfo(applyNo, userId);
//验证测试结果是否达到预期
assertEquals("王小贱", resutls.getName);
}