Junit + Mockito 测试回调(callback) 方法
语言:Java
JDK: Java8 及以上。
前言
Java8推出函数式接口后,就经常使用此特性开发。
在使用Junit + Mockito 时遇到有回调(callback)的函数方法时,遇到几种情况,这里进行记录。
Mockito打桩理解
对于Mockito中打桩个人理解:测试的方法在正常环境需要引入其他类中的方法来支撑(实),但是在mock时,所依赖的其他类都是mock的,这个时候就需要用到Mockito中的打桩来支撑(虚)。
对应代码说明就是:
//打桩,跳过调用,虚构调用返回
doReturn(mockObject).when(ServiceNameA).getXXXXX(anyString());
doReturn(Arrays.asList(new A())).when(ServiceNameB).getXXX(anyInt(),anyString());
doNothing().when(ServiceNameC).updateXXXX(anyList());
//调用
aService.methodName(param);
通用函数回调
//第一种写法:
//对方法返回进行拦截处理
Answer answer = new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] param = invocation.getArguments(); //callback方法的参数列表
Object param1 = param[0]; //第一个入参
Consumer<Object> oConsumer = (Consumer<Object>) param[1]; //Lambda
oConsumer.accept(returnObject);
return oConsumer;
}
};
doAnswer(answer).when(serviceName).method(any());
//第二种:(第一种进阶版)
doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Mock mock = invocation.getMock();
return null;
}})
.when(mock).someMethod();
//第三种:(第二种进阶,个人常用)
doAnswer(invocation ->{
Object[] param = invocation.getArguments(); //callback方法的参数列表
Object param1 = param[0]; //第一个入参
Consumer<Object> oConsumer = (Consumer<Object>) param[1]; //Lambda
oConsumer.accept(returnObject);
return oConsumer;
}).when(mockService).someMethod(anyString());
特殊函数回调
1:多次调用同一方法,每次callback返回的对象不一样。
/**
* 多次调用同方法,每次callback返回对象不一样。
* mehtod(Class<T> type, Object id, Consumer<T> consumer)
* 方法中根据ID获取对象判断是否为type,如果是则consumer返回。
*/
doAnswer(invocation ->{
Object[] arguments = invocation.getArguments();
Object obj = arguments[0]; //依据入参第一个type来实现返回不同对象
if (obj == A_Obj.class){
Consumer<A_Obj> resultConsumer = (Consumer<A_Obj>) arguments[2];
resultConsumer.accept(a_obj);
return resultConsumer;
}else if (obj == B_Obj.class){
Consumer<B_Obj> projectConsumer = (Consumer<B_Obj>) arguments[2];
projectConsumer.accept(b_obj);
return projectConsumer;
}else if (obj == C_Obj.class){
Consumer<C_Obj> networkInfoConsumer = (Consumer<C_Obj>) arguments[2];
networkInfoConsumer.accept(c_obj);
return networkInfoConsumer;
}else{
Consumer<Object> consumer = (Consumer<Object>) arguments[2];
consumer.accept(null);
return consumer;
}
}).when(mockService).method(any(Class.class),any(),any(Consumer.class));
2:遇到在记录