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

为什么Mockito的verify()统计when()调用?和RETURNS_DEEP_STUBS有关吗?

问题原因

该异常确实和Answers.RETURNS_DEEP_STUBS的特性直接相关。

普通Mock对象使用when()做方法存根时,Mockito只会记录方法匹配规则,不会把when()括号内的方法调用计入实际调用统计,因此不会影响后续verify逻辑。但使用深度存根时,为了生成链式调用后续节点的Mock对象,when(mockedObject.putParameter(any()).firstChainCall().secondChainCall())语句中第一步的putParameter(any())会被真实触发,这次调用会被Mockito纳入实际调用统计。加上业务代码中runStuff()触发的一次调用,总共有2次调用,verify默认只预期1次调用,就会抛出TooManyActualInvocations异常。

修复方案
  • 优先推荐调整存根写法,使用doReturn语法规避存根阶段的调用统计:
@RunWith(MockitoJUnitRunner.class)
public class MyTest {

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private FooService mockedObject;

    void setUp() {
        doReturn(HttpStatus.SC_OK).when(mockedObject).putParameter(any()).firstChainCall().secondChainCall();
    }

    @Test
    public void foo() throws Exception {
        runStuff();
        verify(mockedObject).putParameter(any());
    }
}
  • 若不需要深度存根的其他特性,可以移除answer = Answers.RETURNS_DEEP_STUBS配置,手动Mock链式调用每个节点的返回对象,从根源上避免该问题。
  • 不推荐的兼容方案:verify时指定预期调用次数为times(2),该方案相当于把存根阶段的调用也纳入预期,不符合单元测试验证业务逻辑的设计初衷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 17:48:00