首页/开发/软件测试速查/Mockito 打桩与验证
自动化测试66 条

Mockito 打桩与验证

Mockito 用 when(...).thenReturn(...) 定义桩行为、verify(...) 校验调用次数与参数;@Mock 创建替身、@InjectMocks 注入被测对象,配合 MockitoExtension 自动初始化。

软件测试速查开发更新于 2026-10-13

Mockito 是什么

Mockito 是 Java 单元测试中最常用的替身框架:用 @Mock 生成模拟对象、when(...).thenReturn(...) 定义桩行为、verify(...) 校验调用是否按预期发生。它让被测逻辑与外部依赖(下游服务、数据库、时钟)隔离,异常与超时等真实环境难以复现的分支也能稳定构造。配合 MockitoExtension 自动初始化注解,样板代码降到最低。

基本信息

核心三件套打桩 when/thenReturn、验证 verify、替身 @Mock/@Spy
注入方式@InjectMocks 把替身注入被测对象
扩展集成@ExtendWith(MockitoExtension.class) 自动初始化注解
严格模式未使用的桩会报 UnnecessaryStubbingException
参数匹配器any()、eq() 等 ArgumentMatchers 匹配调用参数
参数捕获ArgumentCaptor 捕获调用时的真实参数做断言

示例

示例
@ExtendWith(MockitoExtension.class)
class PaymentTest {
    @Mock Gateway gateway;            // 替身:不调用真实下游
    @InjectMocks PaymentService service;

    @Test
    void pays() {
        when(gateway.charge(100)).thenReturn(true);   // 打桩:定义返回
        assertTrue(service.pay(100));
        verify(gateway).charge(100);                  // 验证:调用发生且参数正确
    }

    @Test
    void timeout_isWrapped() {
        when(gateway.charge(anyInt())).thenThrow(new TimeoutException());  // 异常分支
        assertThrows(PayFailedException.class, () -> service.pay(100));
    }
}

典型使用场景

  • 隔离下游依赖:支付网关、短信通道等外部服务不参与单元测试。
  • 异常分支构造:用 thenThrow 覆盖超时、拒绝、限流等难复现路径。
  • 交互验证:确认服务按协议调用下游且次数、参数正确。
  • 参数断言:用 ArgumentCaptor 捕获请求体,验证序列化与字段组装。
  • 遗留代码加测试:先给难拆的依赖打桩,建立安全网后再重构。
  • 契约收紧:把上下游调用协议固化进 verify,协议变化时测试先报警。

常用能力对照

能力写法说明
定义返回when(x).thenReturn(v)连续调用可用 thenReturn(v1, v2)
抛异常thenThrow(...)覆盖下游出错分支
void 方法doThrow/doNothingvoid 无法用 when(...) 包住
调用验证verify(x).m()配合 times/never/atLeast 控制次数
参数捕获ArgumentCaptor断言调用时实际传入的对象
部分替身@Spy默认调真实方法,谨慎打桩
替身只用于边界:外部服务、时间、随机数这类不可控因素是打桩对象;被测对象内部的协作类尽量真实,打桩打太深测试会与实现细节耦合。
严格模式下未使用的桩会报错:这不是麻烦而是卫生检查,能逼出过期桩与写错的匹配参数,不要图省事整体关闭严格模式。
未打桩的方法调用返回默认值(null、0、false):默认值可能把断言悄悄带过,关键路径应显式定义桩行为。

易错点

  • 对 void 方法用 when(...) 打桩:直接抛出语法层面的异常,应改用 doReturn/doThrow 系列。
  • verify 次数设置过严(times(1)):合理重构后频繁误报,次数断言只用于确有协议要求的场景。
  • 把 mock 当万能胶:内部协作全部打桩,重构一次全量测试失败,测试变成维护负担。
  • 依赖默认返回值断言:桩没定义返回 null,被测代码分支未执行,测试看着过实则没验任何东西。
  • Strictness 一关到底排查未使用桩的问题:错误被掩盖,测试集里堆满过期桩。

数据来源与参考

  • Mockito 官方文档(site.mockito.org)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌