为什么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
相关产品推荐
相关产品推荐

