Stubbing RetryTemplate.execute触发Mockito InvalidUseOfMatchersException排查
解决Mockito Stub RetryTemplate时的InvalidUseOfMatchersException问题
核心原因是:Mockito错误匹配到了RetryTemplate中带3个参数的execute重载方法,而非你目标的单参数版本。
Spring Retry的RetryTemplate本身有多个execute重载,比如:
- 单参数:
execute(RetryCallback<T, E>) - 三参数:
execute(RetryCallback<T, E>, RecoveryCallback<T>, RetryState)
当你用when(retryTemplate.execute(any()))时,Mockito的方法匹配逻辑会扫描所有同名方法,可能误将你的调用绑定到三参数版本上——这就解释了异常里说的"3 matchers expected, 1 recorded"。即便你换成any(RetryCallback.class),类型擦除导致的匹配模糊也可能触发这个问题。
解决方案
方案1:用doAnswer替代when写法(推荐)
doAnswer的语法在处理重载方法时更明确,能避免匹配混淆:
doAnswer(invocation -> { RetryCallback retry = invocation.getArgument(0); return retry.doWithRetry(null); }).when(retryTemplate).execute(any(RetryCallback.class));
方案2:强制指定参数类型,明确匹配单参数方法
通过强制类型转换,让Mockito精准识别单参数的execute方法:
when(retryTemplate.execute((RetryCallback<?, ?>) any())).thenAnswer(invocation -> { RetryCallback retry = invocation.getArgument(0); return retry.doWithRetry(null); });
方案3:用argThat进一步约束参数
如果上述方法仍有问题,可以用更精确的参数匹配器缩小匹配范围:
when(retryTemplate.execute(argThat(callback -> callback instanceof RetryCallback))).thenAnswer(invocation -> { RetryCallback retry = invocation.getArgument(0); return retry.doWithRetry(null); });
内容的提问来源于stack exchange,提问作者techie11
相关产品推荐
相关产品推荐

