JUnit测试用when().then()抛InvalidUseOfMatchers错误如何解决?
问题根因说明
初始InvalidUseOfMatchers错误
你遇到的第一个报错有两个核心原因:
@InjectMocks注解生成的是MyUtilityClass的真实实例,不是Mockito的Mock/Spy代理对象,无法直接对真实实例的方法做打桩(stub)操作。- 你后续修改的代码里,把参数匹配器用在了错误的位置:
any*系列匹配器只能用于when()结构里的方法参数处,既不能用来代替when()里的调用对象,也不能作为thenReturn()的返回值,返回值必须传入具体的固定值。
修改后空指针错误
你把when的调用对象替换为any(MyUtilityClass.class)的写法完全不符合Mockito语法,不会生成有效的方法桩,后续代码调用inheritedMethod时会直接执行父类的真实逻辑,没有预设返回值就会触发空指针。
正确解决方案
你需要把测试对象改成Spy代理对象,实现「大部分方法走真实逻辑、只打桩指定继承方法」的效果,修改后的测试代码如下:
@ExtendWith(MockitoExtension.class) public class MyUtilityClassTest { // 同时加@Spy和@InjectMocks,既支持部分方法打桩,又能注入配置字段 @Spy @InjectMocks private MyUtilityClass muc; // 如果@Value标注的value字段无法自动注入,用反射工具手动赋值即可 @BeforeEach void init() { org.springframework.test.util.ReflectionTestUtils.setField(muc, "value", "testConfigVal"); } @Test void test() { // 对Spy对象打桩用doReturn,避免触发真实方法执行 doReturn("EXPECTED_VALUE").when(muc).inheritedMethod(anyMap(), anyString()); var response = muc.getData(); assertEquals("EXPECTED_VALUE", response.getValue()); } }
额外说明
- 对Spy对象打桩优先用
doReturn(返回值).when(代理对象).方法名(参数)的写法,不要用when(代理对象.方法名()).thenReturn(),后者会先执行一次真实方法,可能带来不必要的副作用。 - 如果方法的任意一个参数用了匹配器,所有参数都必须用匹配器,比如不能出现
inheritedMethod(new HashMap(), anyString())的写法,否则也会报匹配器使用错误。
内容的提问来源于stack exchange,提问作者Agha Salman
相关产品推荐
相关产品推荐

