You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito多次mock同一方法时when().thenReturn()返回错误值如何解决

Mockito多次Stub同一方法返回值不符合预期的解决方案

问题根因

Mockito对同一方法的Stub规则会按逆序匹配:即优先匹配最后声明的规则,匹配不到才会向前查找更早的规则。该问题通常由两个原因导致:

  1. Stub时使用的参数(Object1/Object2)和实际调用时传入的参数equals判断不相等,导致前面的规则匹配失败,最终命中最后一次配置的规则
  2. 规则顺序配置错误,更宽泛的匹配规则放在了更具体的规则之后,覆盖了前面的窄范围规则

调整方案

方案1:使用明确的等值匹配器

直接按需求用具体参数值+eq()匹配器声明规则,确保匹配逻辑符合预期:

when(serviceA.findById(any(String.class))).thenReturn(Object1);
// 明确匹配入参为1的请求
when(serviceB.getById(eq(1))).thenReturn(FirstValue);
when(serviceC.convert(any(Integer.class), any(Integer.class))).thenReturn(Object2);
// 明确匹配入参为2的请求
when(serviceB.getById(eq(2))).thenReturn(LatestValue);
when(serviceA.save(Object2)).then(returnsFirstArg());

方案2:调整规则顺序

如果需要保留对象参数匹配的写法,先确认Object1和Object2的equals、hashCode方法逻辑正确,再把更具体的规则放在更靠后的位置:

// 先声明相对宽泛的规则
when(serviceA.findById(any(String.class))).thenReturn(Object1);
when(serviceC.convert(any(Integer.class), any(Integer.class))).thenReturn(Object2);
when(serviceA.save(Object2)).then(returnsFirstArg());
// 后声明更具体的serviceB规则,避免被覆盖
when(serviceB.getById(Object1)).thenReturn(FirstValue);
when(serviceB.getById(Object2)).thenReturn(LatestValue);

方案3:使用doReturn写法规避Spy对象的副作用

如果serviceB是Spy对象而非纯Mock对象,when().thenReturn()的写法会触发一次真实方法调用,可能导致匹配逻辑异常,换用doReturn写法即可:

doReturn(FirstValue).when(serviceB).getById(eq(1));
doReturn(LatestValue).when(serviceB).getById(eq(2));

同参数多返回值场景补充

如果是同一个入参、多次调用需要返回不同值,可以直接链式配置返回值:

// 第一次调用返回FirstValue,第二次及之后调用返回LatestValue
when(serviceB.getById(anyInt())).thenReturn(FirstValue, LatestValue);

内容的提问来源于stack exchange,提问作者jimmy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:15:05