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

使用@InjectMocks注入服务时无法传入Mock对象触发空指针异常

问题根因
  • 手动初始化@InjectMocks字段触发空指针:@Mock标注的字段仅在MockitoAnnotations.openMocks(this)执行后才会被实例化为Mock对象,类字段声明阶段someService的值为null,此时传入构造函数的List内包含null元素,遍历调用getCustomEnum()时触发空指针。
  • 不手动初始化@InjectMocks字段触发注入失败:@InjectMocks默认不会自动将单个SomeService类型的Mock对象包装为List<AbstractSomeService>注入到构造函数中,导致构造函数拿到的List参数为null,调用forEach时触发空指针。

额外注意:你提供的UserService代码存在两处笔误:一是someMap的泛型定义和实际插入的键值类型相反,二是没有初始化Map实例,会额外引发空指针,修正后定义如下:

private final Map<CustomEnum, AbstractSomeService> someMap = new HashMap<>();
解决方案

方案1:手动构造UserService实例(最推荐)

放弃使用@InjectMocks,在Mock对象初始化完成后手动实例化UserService,逻辑清晰不易出错:

@Mock
private SomeService someService;

// 去掉@InjectMocks注解,在setUp阶段手动初始化
private UserService userService;

@BeforeEach
void setUp() {
    MockitoAnnotations.openMocks(this);
    // 此时someService已经完成Mock初始化,再构造UserService
    userService = new UserService(Collections.singletonList(someService));
}

@Test
public void testFixedJunit() {
    userService.logicExecution();
}

方案2:适配@InjectMocks的自动注入规则

如果需要保留@InjectMocks注解,可以提前声明List类型的Mock依赖供注入:

@Mock
private SomeService someService;
// 新增List类型的Mock字段匹配构造函数参数类型
@Mock
private List<AbstractSomeService> someServiceList;

@InjectMocks
private UserService userService;

@BeforeEach
void setUp() {
    MockitoAnnotations.openMocks(this);
    // 手动给List Mock配置返回规则
    when(someServiceList.iterator()).thenReturn(Collections.singletonList(someService).iterator());
    when(someServiceList.size()).thenReturn(1);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:18:03