mockito参数匹配器要求stub和verify阶段风格统一,所有参数必须全用匹配器,禁止混用字面值与匹配器,否则抛invaliduseofmatchersexception;常用匹配器包括anyint()、eq()、contains()、argthat()等,verify需与stub匹配逻辑一致,并注意null、基本类型及自定义描述等陷阱。

Java 单元测试中使用 Mockito 验证参数匹配器,核心在于:**在 stub(when)和 verify 两个阶段保持匹配器风格一致,且所有参数都需用匹配器表达**。不混用字面值和匹配器,否则会抛出 `InvalidUseOfMatchersException`。
必须统一使用匹配器
一旦某个方法调用中用了任意一个匹配器(如 anyInt()、eq("abc")),那该方法的所有参数都得是匹配器——不能一部分写具体值,一部分用匹配器。
- ✅ 正确:
when(map.put(anyInt(), eq("hello"))).thenReturn(true); - ❌ 错误:
when(map.put(1, eq("hello"))).thenReturn(true);→ 编译通过但运行时报错 - ✅ 补救写法:把字面值也转成匹配器,比如
eq(1)替代1
常用匹配器及适用场景
根据参数类型和验证意图选择合适匹配器:
- anyString()、anyInt():当只关心“有没有被调用”,不关心具体值时
- eq("expected"):验证参数是否等于某个确切值(推荐用于关键业务字段,如邮箱、状态码)
- contains("sub")、startsWith("pre"):适用于字符串内容部分匹配
- argThat(x -> x.size() == 2):自定义逻辑,比如检查集合长度、对象属性满足条件
- intThat(x -> Set.of(100, 200, 300).contains(x)):判断原始类型是否属于某几个预设值之一
verify 阶段也要用匹配器对齐
stub 时用了匹配器,verify 时也得用同样的匹配器逻辑,否则验证失败。
- 示例:你 stub 了
when(service.process(anyLong())).thenReturn("ok"); - 那么 verify 应写为:
verify(service).process(anyLong()); - 若想验证是否传了特定值,应改用
eq(123L),且 stub 也得同步改成when(service.process(eq(123L))).thenReturn("ok");
避免常见陷阱
几个高频出错点需特别注意:
- 在
verify(..., times(n))中漏掉匹配器,仍写具体值 → 直接失败 - 对 null 值使用
eq(null)→ 改用isNull()更安全 - 误用
any()匹配基本类型(如 int)→ 应用anyInt(),因为any()返回 Object,可能引发自动装箱问题 - 自定义
ArgumentMatcher时未重写describeTo(Description)→ 虽不影响功能,但失败时错误信息不友好;建议搭配argThat(..., "size==2")提供描述
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











