本文详解 Mockito 中 NotAMockException 的根本原因及解决方案,重点说明 @InjectMocks 与 @Mock 的职责区分,并提供可直接运行的单元测试最佳实践。
本文详解 mockito 中 `notamockexception` 的根本原因及解决方案,重点说明 `@injectmocks` 与 `@mock` 的职责区分,并提供可直接运行的单元测试最佳实践。
在使用 Mockito 进行单元测试时,verify() 方法用于确认某个被测对象的依赖是否按预期被调用。但若错误地将待测服务本身标记为 @Mock,就会触发 NotAMockException —— 因为 verify(vinService) 要求 vinService 是一个由 Mockito 创建并管理的 mock 对象,而当前代码中 vinService 虽被 @Mock 声明,却未被注入到 carService 实例中,且 carService 自身又被错误地声明为 @Mock,导致其内部持有的 vinService 字段仍为 null 或原始实例,而非 mock。
✅ 正确做法:明确角色分工
- @Mock:仅用于被依赖的协作对象(如 VinService),由 Mockito 创建模拟实现;
- @InjectMocks:用于被测主对象(如 CarService),Mockito 将自动把所有 @Mock 标注的依赖通过构造函数、setter 或字段注入;
- ❌ 禁止对被测类本身使用 @Mock(除非你刻意要 mock 其行为——此时它就不是“被测对象”,而是“协作对象”)。
✅ 推荐写法(推荐使用 @InjectMocks + @Mock)
@ExtendWith(MockitoExtension.class)
public class CarServiceTest {
private static final String VIN = "1G100000000000000";
@Mock
private VinService vinService; // ✅ 正确:mock 依赖项
@InjectMocks
private CarService carService; // ✅ 正确:被测对象,自动注入 vinService
@Test
void vinShouldBeCheckedSuccessfully() {
// when
carService.checkCar(VIN);
// then
verify(vinService, times(1)).checkVin(
anyList(),
eq(VIN),
any(Consumer.class)
);
}
}? 注意:方法名需严格匹配(原代码中 checkVIN vs 实际方法 checkVin),建议使用 eq(VIN) 替代 anyString() 提高断言准确性;any(Consumer.class) 比 any() 更语义清晰。
⚠️ 补充说明:手动构造场景(不推荐,仅作理解)
若 CarService 构造函数显式接收 VinService,也可手动注入:
@Test
void vinShouldBeCheckedSuccessfully_ManualInjection() {
VinService mockVinService = mock(VinService.class);
CarService carService = new CarService(mockVinService); // 手动传入 mock
carService.checkCar(VIN);
verify(mockVinService, times(1)).checkVin(anyList(), eq(VIN), any(Consumer.class));
}但此方式失去 @InjectMocks 的自动化优势,且无法复用 @Mock 生命周期管理,强烈建议优先采用 @InjectMocks 方案。
? 总结关键点
- verify() 只能作用于真正的 mock 对象(由 Mockito.mock() 或 @Mock 创建);
- @Mock 不等于“自动注入”,它只创建 mock 实例;注入需靠 @InjectMocks 或手动完成;
- @InjectMocks 必须配合 @Mock(或 @Spy)才能生效,否则依赖字段为 null;
- 测试前确保类结构支持注入(如字段非 final,或提供构造函数/Setter);
- 使用 MockitoExtension 时,务必检查 JUnit 5 版本兼容性(≥ 5.6.0)及 Mockito 4+。
遵循以上原则,即可彻底规避 NotAMockException,写出清晰、可靠、可维护的 Mockito 单元测试。

















