You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Mockito覆盖代码else分支(#def)提升Sonar代码覆盖率?

解决单元测试覆盖#else分支的问题

你的问题出在只mock了List的isEmpty()方法,但没把这个mock的List关联到代码里的result.result()返回值上。代码里的mobileList来自getSomeDetails返回的Future的执行结果,所以得从根源上让这个Future返回成功的Result,且Result携带非空列表。

具体步骤如下:

  1. 模拟成功的Result对象
    创建一个Result实例,让它的succeeded()返回true,同时让result()返回一个非空列表(用真实列表比mock List更简单):

    Result<List<String>> mockResult = Mockito.mock(Result.class);
    // 标记Result为成功状态
    Mockito.when(mockResult.succeeded()).thenReturn(true);
    // 准备一个非空列表,直接用真实实例即可
    List<String> nonEmptyMobileList = Arrays.asList("13800138000", "13900139000");
    // 让Result返回这个非空列表
    Mockito.when(mockResult.result()).thenReturn(nonEmptyMobileList);
    
  2. 模拟getSomeDetails返回的Future
    让getSomeDetails方法返回的Future在触发onComplete时,把上面的mockResult传入回调:

    // 假设你的业务类是MyService,用spy保留原有逻辑或直接mock
    MyService myService = Mockito.spy(new MyService());
    Future<List<String>> mockFuture = Mockito.mock(Future.class);
    
    // 模拟Future的onComplete行为:调用回调时直接传入mockResult
    Mockito.doAnswer(invocation -> {
        // 获取传入的回调函数
        Function<Result<List<String>>, Void> callback = invocation.getArgument(0);
        // 执行回调,传入成功的Result
        callback.apply(mockResult);
        return null;
    }).when(mockFuture).onComplete(Mockito.any());
    
    // 让getSomeDetails返回这个mockFuture
    Mockito.when(myService.getSomeDetails(Mockito.anyString(), Mockito.any(User.class)))
            .thenReturn(mockFuture);
    
  3. 执行测试并验证
    调用你的业务方法后,代码会触发onComplete回调,此时mobileList.isEmpty()会返回false,自然会走到标记为#def的else分支,完成代码覆盖。

如果坚持要用mock的List,只需要把上面的nonEmptyMobileList换成你之前mock的List即可,但真实列表的写法更简洁,不容易出错。

内容的提问来源于stack exchange,提问作者Stunner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 11:17:18