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

JUnit+Mockito测试静态方法报错:参数匹配器误用/错位

问题

我有一个类,其公共非静态方法内部调用了静态方法,使用JUnit结合Mockito测试时需要Mock该静态方法,但测试代码报错。以下是我的代码及报错信息:

class DummyClass {

    public boolean filter(CharSequence source) {
        return Character.isHighSurrogate(source.charAt(7));
    }
}

@Test
public void testDummyCharacterMockedStatic() {
   try (MockedStatic<Character> mocked = Mockito.mockedStatic(Character.class)) {
       CharSequence source = "안녕하세요 세계";
       mocked.when(() -> Character.isHighSurrogate(anyChar())).thenReturn(true);
       DummyClass d = new DummyClass();
       assertTrue(d.filter(source));
   }
}

报错信息翻译:

检测到参数匹配器放置错误或使用错误:
-> 在 DummyTest.lambda$testDummyCharacterMockedStatic$0(DummyTest.java:37)
你不能在验证或存根之外使用参数匹配器。
参数匹配器的正确用法示例:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))

如果最后一个匹配器返回类似any()的对象,但存根方法的签名需要基本类型参数,可能会出现NullPointerException,之后也会显示此消息。这种情况下,请使用基本类型的替代匹配器。
when(mock.get(any())); // 错误用法,会抛出NPE
when(mock.get(anyInt())); // 正确用法

此外,如果你对无法被Mock的方法使用参数匹配器,也会出现此错误。以下方法无法被存根/验证:final/private/equals()/hashCode()。不支持Mock非公共父类中声明的方法。

解决方案

你的代码存在两个核心问题:

  1. Character.isHighSurrogate是final静态方法,Mockito默认不支持Mock final方法
    JDK中Character.isHighSurrogate被定义为public static final boolean isHighSurrogate(char ch),属于final方法。Mockito核心库无法Mock final方法,需要引入mockito-inline扩展来支持Mock final类和方法。

    若使用Maven,需在pom.xml中添加依赖:

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-inline</artifactId>
        <version>4.0.0</version> <!-- 使用最新稳定版本即可 -->
        <scope>test</scope>
    </dependency>
    
  2. 参数匹配器需明确归属类
    原代码中anyChar()未指定归属类,需改为Mockito.anyChar(),确保匹配器的调用符合Mockito的语法规范。

修正后的测试代码:

@Test
public void testDummyCharacterMockedStatic() {
    try (MockedStatic<Character> mockedCharacter = Mockito.mockedStatic(Character.class)) {
        // 存根:无论传入什么char值,都返回true
        mockedCharacter.when(() -> Character.isHighSurrogate(Mockito.anyChar())).thenReturn(true);
        
        DummyClass d = new DummyClass();
        CharSequence source = "안녕하세요 세계";
        assertTrue(d.filter(source));
    }
}

若不需要匹配任意参数,也可直接指定具体参数值存根,例如:

mockedCharacter.when(() -> Character.isHighSurrogate('안')).thenReturn(true);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:37:44