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

Mockito Mock私有方法调用的外部方法返回空列表问题排查

解决Mockito Mock search()返回空列表的问题

这种情况我之前踩过好几次坑,大概率是Mock的配置或者调用链路出了问题,咱们一步步来排查和解决:

1. 确保外部依赖被正确Mock并注入被测类

如果search()是某个外部类(比如ExternalService)的方法,你得保证被测类使用的是Mock实例,而不是自己new出来的真实对象。举个例子:

  • 被测类要通过构造方法/Setter注入外部依赖,而不是在类内部直接new ExternalService();
  • 测试类里用@Mock标记外部依赖,@InjectMocks标记被测类,同时别忘了加Mockito的扩展注解(JUnit 5用@ExtendWith(MockitoExtension.class),JUnit 4用@RunWith(MockitoJUnitRunner.class)),不然注解不会生效。

2. 检查Mock的方法签名是否完全匹配

如果search()有参数,你Mock的时候参数不匹配,Mockito就会返回默认值(空列表)。比如:

  • 实际调用是externalService.search("keyword"),但你Mock的是when(externalService.search()).thenReturn(...),这就不匹配;
  • 解决方法:用匹配器(比如any()、anyString())或者具体参数来匹配,比如when(externalService.search(anyString())).thenReturn(Arrays.asList("a", "b"))。

3. 验证Mock方法是否真的被调用了

有时候看起来调用了a()→B()→search(),但实际可能因为逻辑分支没走到,或者调用的不是Mock实例。你可以在测试最后加一句验证代码:

verify(externalService, times(1)).search(/* 对应参数 */);

如果抛出TooFewActualInvocations异常,说明search()根本没被调用,那得检查a()是否正确触发了B(),或者B()里的调用逻辑有没有问题。

4. 避免在被测类内部实例化外部依赖

如果你的被测类里是这么写的:

private void B() {
    ExternalService service = new ExternalService();
    List<String> result = service.search();
}

那不管你怎么MockExternalService都没用,因为这里每次调用B()都会new一个新的真实实例。解决方法是把ExternalService作为依赖注入到被测类中,比如通过构造方法传入。

示例代码参考

被测类

public class MyClass {
    private final ExternalService externalService;

    // 构造注入外部依赖
    public MyClass(ExternalService externalService) {
        this.externalService = externalService;
    }

    public void a() {
        B();
    }

    private void B() {
        List<String> searchResult = externalService.search();
        // 你的业务逻辑
    }
}

// 外部服务接口
public interface ExternalService {
    List<String> search();
}

测试类

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Arrays;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class MyClassTest {
    @Mock
    private ExternalService externalService;

    @InjectMocks
    private MyClass myClass;

    @Test
    public void testA_WhenCalled_ShouldUseMockedSearchResult() {
        // 配置Mock返回预期列表
        when(externalService.search()).thenReturn(Arrays.asList("item1", "item2"));

        // 调用公共方法
        myClass.a();

        // 验证search()被调用了一次
        verify(externalService, times(1)).search();
    }
}

按照上面的步骤排查,应该就能解决Mock返回空列表的问题了~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:26:04