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:遇到在记录