Mockito 隔离外部依赖的核心是控制行为、验证交互、守住边界,只 mock 触发副作用的依赖(如数据库、远程调用),纯数据对象无需 mock;正确选用 mock()、@Mock 或 @MockBean;stub 要精准覆盖关键路径;verify 必须确认方法调用次数、参数及是否误调用。

用 Mockito 隔离外部依赖,关键不是“造个假对象”,而是控制行为、验证交互、守住边界。它不替代真实逻辑,而是帮你把测试焦点牢牢锁在被测类本身。
明确哪些依赖必须 Mock
不是所有字段都要 mock,只 mock 那些会触发副作用或不可控行为的依赖:
- 数据库访问层(如
UserRepository、JdbcTemplate) - 远程调用客户端(如
RestTemplate、FeignClient 实现类) - 第三方 SDK 或工具类(如短信发送器、文件上传服务)
- 含复杂状态或时间敏感逻辑的组件(如定时任务调度器、本地缓存管理器)
如果某个依赖只是纯数据容器(比如 DTO、VO),或内部无 IO/网络/状态,通常不需要 mock —— 直接 new 或用构造器注入更清晰。
用对创建方式:mock() vs @Mock vs @MockBean
不同场景选不同创建方式,混淆会导致测试不稳定:
立即学习“Java免费学习笔记(深入)”;
-
Mockito.mock(Interface.class):适合纯单元测试(无 Spring 上下文),手动管理 mock 实例 -
@Mock+@ExtendWith(MockitoExtension.class):JUnit 5 推荐写法,自动注入 mock 字段,无需手动初始化 -
@MockBean:仅用于@SpringBootTest或集成测试中,会替换 Spring 容器里的 Bean,慎用于纯单元测试(会启动上下文,变慢且易干扰)
记住:一个测试类里别混用 @Mock 和 mock(),容易漏掉初始化或重复 mock。
Stub 行为要覆盖关键路径
stub 不是随便 return null,而是按测试目标精准设定返回值:
- 测试正常流程 →
when(repo.findById(1)).thenReturn(new User(1, "Alice")) - 测试空结果 →
when(repo.findById(999)).thenReturn(null)或Optional.empty() - 测试异常分支 →
doThrow(new RuntimeException("DB fail")).when(repo).save(any()) - 测试多次调用不同响应 →
when(service.process()).thenReturn("first").thenReturn("second")
避免写 when(mock.method()).thenReturn(null) 这类模糊 stub,容易掩盖 NPE 或逻辑缺陷。
Verify 调用而非只看结果
光断言返回值不够,还要确认是否按预期跟依赖发生了交互:
- 该调用的方法有没有被调用?
verify(repo).save(user) - 调用了几次?
verify(repo, times(1)).findById(123) - 参数是否匹配?
verify(repo).update(eq(123), anyString()) - 有没有不该调用的方法被误触?
verifyNoInteractions(logger)
尤其对 void 方法或事件发布类,verify 是唯一能确认行为的方式。


















