使用Mockito时注入的SensorRepository为null而非Mock对象的问题排查
问题根源与解决方案
你的测试代码中@Mock注解的对象为null,核心原因是JUnit版本与Mockito注解的适配问题,以及部分细节配置错误,以下是具体分析和修复方案:
1. 最常见原因:JUnit版本与Mockito注解不兼容
如果你使用的是JUnit 5(Jupiter):
@RunWith(MockitoJUnitRunner.class)是JUnit 4的专属注解,JUnit 5完全不识别该注解,导致Mockito无法初始化@Mock和@InjectMocks标记的对象,最终出现null。
修复步骤:- 替换注解为JUnit 5的扩展注解
@ExtendWith(MockitoExtension.class) - 确保引入
mockito-junit-jupiter依赖(而非JUnit 4的mockito-junit4) - 修改后的测试类代码:
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 static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class SensorsServiceImplTest { @Mock private SensorRepository sensorRepository; // 建议注入实现类而非接口,避免Mockito代理生成的潜在问题 @InjectMocks private SensorsServiceImpl sensorService; @Test public void wasSensorSaved(){ Sensor sensor = Sensor.builder().id(1L).build(); when(sensorRepository.save(sensor)).thenReturn(sensor); Sensor savedSensor = sensorService.save(sensor); assertThat(savedSensor).isNotNull(); } } - Maven依赖示例:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>4.11.0</version> <!-- 使用最新稳定版 --> <scope>test</scope> </dependency>
- 替换注解为JUnit 5的扩展注解
如果你确实在使用JUnit 4:
- 检查测试类是否为
public修饰(部分老版本Mockito对包私有类的注解支持有问题) - 确保引入了
mockito-junit4依赖:<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit4</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
- 检查测试类是否为
2. 次要可能原因:@InjectMocks注入目标选择不当
你原本的代码中@InjectMocks标记的是SensorService接口,Mockito需要为接口生成代理对象,虽然大部分情况可行,但不如直接注入实现类SensorsServiceImpl稳定——因为@InjectMocks本质是通过反射为具体类的字段注入依赖,接口没有可注入的字段,代理生成过程中可能出现意外问题。
3. 验证依赖是否正确
确保你的测试依赖中没有同时引入JUnit 4和JUnit 5的冲突依赖,这种冲突会导致注解处理逻辑混乱,优先清理依赖树中的冗余JUnit依赖。
内容的提问来源于stack exchange,提问作者Matvey Androsyuk
相关产品推荐
相关产品推荐

