Mockito调用NamedParameterJdbcTemplate参数匹配器异常求助
解决Mockito InvalidUseOfMatchersException 错误
这个错误是Mockito最常见的使用误区之一,我来帮你拆解问题根源和解决办法:
错误核心原因
你碰到的3 matchers expected, 2 recorded错误,本质是Mockito的规则限制:当你使用参数匹配器(比如anyString()、anyMap())时,方法的所有参数必须全部使用匹配器,不能混合具体值;反之,所有参数都用具体值也可以,但绝对不能混搭。
你可能会疑惑:我明明第三个参数用了eq(Integer.class)啊?这里有个极易踩坑的细节:
1. 错误导入了Hamcrest的eq匹配器
如果你的代码里不小心导入了org.hamcrest.Matchers.eq而非org.mockito.Mockito.eq,这个eq就不是Mockito的参数匹配器,而是Hamcrest的断言匹配器。此时Mockito只会识别前两个anyString()、anyMap()是自己的匹配器,第三个参数会被当成普通具体值,自然就会报"期望3个匹配器,只找到2个"的错误。
2. when(...).thenReturn()语法的潜在问题
when(mock.method(...)).thenReturn()的语法会先"调用"一次mock对象的方法(虽然是mock,但参数解析逻辑可能有差异),某些场景下会导致匹配器识别异常。
解决方案
方案1:确保使用Mockito的参数匹配器
检查你的导入语句,要么明确使用Mockito.eq(),要么导入Mockito的静态方法:
import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.anyMap; import static org.mockito.Mockito.eq;
修正后的测试代码:
@Test public void testGetScheduleTotalCount() { when(namedParameterJdbcTemplate.queryForObject( anyString(), anyMap(), eq(Integer.class) )).thenReturn(2); }
方案2:换用doReturn().when()语法
这种语法不会提前调用mock方法,参数匹配器的识别更稳定,尤其适合复杂mock场景:
@Test public void testGetScheduleTotalCount() { doReturn(2).when(namedParameterJdbcTemplate) .queryForObject(anyString(), anyMap(), eq(Integer.class)); }
方案3:使用精准的Map匹配器(可选)
如果你的方法要求Map<String, ?>类型参数,可以用anyMapOf指定泛型,让mock更精准:
@Test public void testGetScheduleTotalCount() { doReturn(2).when(namedParameterJdbcTemplate) .queryForObject(anyString(), anyMapOf(String.class, Object.class), eq(Integer.class)); }
内容的提问来源于stack exchange,提问作者Srinu
相关产品推荐
相关产品推荐

