为什么我的Kotlin Spring Boot测试代码会触发Mockito的InvalidUseOfMatchersException
异常触发核心原因
该异常在Kotlin+Mockito技术栈下属于典型适配问题,不属于参数匹配器用在基础类型的场景,两个最常见的触发点如下:
- 待Mock的
shouldProceed方法是final类型:Kotlin的类和方法默认都是final修饰,如果AuthFilter类和shouldProceed方法没有手动加open修饰符,Mockito无法正常代理该方法,会导致参数匹配器的调用栈错位,抛出InvalidUseOfMatchersException。 - 非空参数和Mockito默认匹配器冲突:Mockito原生的
any()匹配器默认返回null,如果shouldProceed方法的入参声明为Kotlin非空类型,null传入会触发Kotlin的空校验,打断Mockito的匹配逻辑,抛出异常。
解决方法
方案一(推荐):使用Mockito-Kotlin适配库
Mockito-Kotlin专门对Kotlin语法做了适配,匹配器会自动返回对应类型的非空默认值,不会触发空校验,同时兼容final类/方法的匹配逻辑:
- 引入Mockito-Kotlin测试依赖,Gradle Kotlin DSL引入示例:
testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
Maven引入示例:
<dependency> <groupId>org.mockito.kotlin</groupId> <artifactId>mockito-kotlin</artifactId> <version>4.1.0</version> <scope>test</scope> </dependency>
- 替换原测试代码中
any方法的导入,将import org.mockito.ArgumentMatchers.any替换为import org.mockito.kotlin.any,原有stub逻辑不需要修改即可正常运行。
方案二:原生Mockito适配
如果不需要引入额外依赖,可按如下步骤调整:
- 开启Mockito对final类/方法的mock支持:在测试资源目录下创建
mockito-extensions/org.mockito.plugins.MockMaker文件,写入内容mock-maker-inline。 - 修改stub代码,手动兜底非空值,避免触发Kotlin空校验:
@BeforeEach fun setup() { assertNotNull(mockedAuthFilter) `when`( mockedAuthFilter.shouldProceed( any(HttpServletRequest::class.java) ?: HttpServletRequest::class.java.newInstance(), any(AuthConfig::class.java) ?: AuthConfig::class.java.newInstance() ) ).thenReturn(true) }
内容的提问来源于stack exchange,提问作者Kai。
相关产品推荐
相关产品推荐

