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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:02:10