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
相关产品推荐
相关产品推荐

