Mockito模拟依赖的核心在于正确注入mock实例而非仅创建:需通过@InjectMocks或手动构造传入,配合@ExtendWith(MockitoExtension.class)初始化,再用when/verify定义行为与验证调用,区分@Mock(全模拟)和@Spy(部分模拟)。

Mockito 模拟依赖的核心是:让被测对象真正使用你控制的 mock 实例,而不是 null、默认实例或真实对象。关键不在“创建 mock”,而在“注入 mock”。
明确依赖注入方式
Mockito 不会自动把 @Mock 对象塞进你的被测类里——它只负责生成模拟对象。是否能生效,取决于你如何构造被测对象:
- 用 @InjectMocks 注解声明被测对象,Mockito 会尝试通过构造函数、setter 或字段注入已标记为 @Mock 的依赖(推荐用于 Spring 管理的类)
- 手动构造时,必须显式传入 mock 实例,例如
new Service(mockDao);否则 new Service() 内部依赖仍是 null 或真实实现 - 避免混合使用:不要一边用 @Autowired 在类中声明依赖,一边在测试里 new 实例却不传依赖,这是
Wanted but not invoked错误最常见的原因
正确初始化注解
仅加 @Mock/@InjectMocks 不够,必须触发初始化:
- JUnit 5 推荐加
@ExtendWith(MockitoExtension.class)在测试类上,全自动处理生命周期 - 若不用扩展,需在
@BeforeEach中调用MockitoAnnotations.openMocks(this) - 不初始化会导致所有 @Mock 字段为 null,后续 when/verify 全部失效
定义行为与验证调用
mock 创建并注入后,才进入逻辑控制阶段:
立即学习“Java免费学习笔记(深入)”;
- 用
when(mock.method(...)).thenReturn(...)预设返回值(支持 anyString()、eq(1) 等匹配器) - 对 void 方法,用
doThrow(...).when(mock).method()或doAnswer(...).when(mock).method() - 执行被测方法后,用
verify(mock, times(1)).method(...)确认是否按预期调用,可加参数校验
区分 Mock 和 Spy
不是所有依赖都适合全量 mock:
- @Mock:方法默认返回 null/0/false,完全不执行原逻辑,适合外部服务、DAO、HTTP 客户端等
- @Spy:基于真实对象创建,未 stub 的方法仍走原逻辑,适合需要部分拦截的本地工具类或包装器
- 误用 spy 可能导致真实 IO 或状态变更,破坏测试隔离性


















