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

