最强Mock工具TestableMock使用

最近研究了下阿里出品的Mock工具TestableMock,感觉在Mock这块儿,它是真的比现有的Mock工具强悍太多了。

官网简介:

TestableMock

官网说:开发者真正关心的只有一件事,"这个调用,在测试的时候要换成那个假的Mock方法"。

但我觉得还得补充上一句,开发者还关心能够很方便地Mock出依赖的第三方返回不同结果的情况。

现在,假设我们有个业务代码findByCondition所在的被测试类AService:

public class AService{

    private RPCService rpcService;

    publice Boolean findByCondition(JsonObject query){

        // doSomething... 
        // and doSomething... 

        RPCResult rpcResult = rpcService.query(query);
        if(rpcResult.code = "Success"){
           // doSomething... 
        }else {
           // doSomething... 
        }
    }

}

这是一个很常见的业务场景,依赖第三方的返回结果来决定业务的走向。我们在写单测的时候,需要把RPC调用过程给Mock出来,同时要能模拟出RPC响应不同结果的情况。

如果用旧的Mock工具,可以通过When  Then语法定义出Mock在不同参数下的响应值,类似于这样:

 when(mIntent.getAction()).thenReturn("com.yn.test.mockito");
 when(mIntent.getStringExtra("Name")).thenReturn("Whyn");

需要预定义每种情况下的请求参数,而且写过单测的就知道,参数的字段少的时候还行,多的时候,构建参数就已经是一件很麻烦的事情了,更麻烦的是,如果要命中这个When条件,基本上所有字段都需要符合才行,懂得都懂。

我个人感觉testable强就强在,它可以很方便地定义在各种情境下的返回值,这是官网的说明

TestableMock

简单来说,通过 MOCK_CONTEXT 为Mock设置测试场景,在Mock方法中设置针对不同场景的响应。那上述被测试类的单测就可以这么写:

public class AServiceTest{

    private AService aService = nwe AService();


    // 放置Mock方法的地方
    public static class Mock {

        
        // 使用`targetMethod`指定需Mock的方法名
        // 此方法本身现在可以随意命名,但方法参数依然需要遵循相同的匹配规则
        @MockInvoke(targetClass = RPCService.class, targetMethod = "query")
        private RPCResult query(JsonObject query) {
            switch((String)MOCK_CONTEXT.get("RPC调用")) {
            case "查询有结果":
                List<String> list = new ArrayList;
                list.put("1");
                list.put("2");
                list.put("3");
                return new RPCResult(list);
            case "查询结果为空":
                List<String> list = new ArrayList;
                list.put("1");
                list.put("2");
                list.put("3");
                return new RPCResult(list);
            case "RPC调用异常":
                throw new NetworkException();
            default:
                return null;
           }
        }
    }


    @Test
    publice Boolean testFindByCondition(JsonObject query){
        MOCK_CONTEXT.put("RPC调用", "查询有结果");
        assertEquals(true, aService.findByCondition());
        MOCK_CONTEXT.put("RPC调用", "查询结果为空");
        assertEquals(false, aService.findByCondition());
        MOCK_CONTEXT.put("RPC调用", "RPC调用异常");
        assertEquals(false, aService.findByCondition());
    }

}

这个写法的好处:

1、Mock的方法跟测试代码分离,测试方法中就只剩定义要测试的情景跟预期的结果即可

2、在定义Mock方法的时候,返回值跟入参解偶,不再需要花费心思去关注测试方法的入参是不是命中了when条件

3、Mock方法可以复用,这个可以参考官方文档

这样写Mock是不是很清晰了呢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值