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非公共父类中声明的方法。
你的代码存在两个核心问题:
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>参数匹配器需明确归属类
原代码中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

