Kotlin中Mockito匹配默认参数时的方法验证问题
Kotlin + Mockito 处理@JvmOverloads方法的参数匹配问题
方法签名
@JvmOverloads fun submit( message: PushMessage, targetPackage: String, intercept: Boolean = false) {
第一次测试尝试
我用以下代码测试:
verify(service.messageBroadcaster, times(1)) .submit(any(PushMessage::class.java), any(String::class.java))
Mockito报错:
Invalid use of argument matchers! 3 matchers expected, 2 recorded:
第二次测试尝试
改用三个匹配器测试:
verify(service.messageBroadcaster, times(1)) .submit(any(PushMessage::class.java), any(String::class.java), any(Boolean::class.java))
得到错误:
Argument(s) are different! Wanted: messageBroadcaster.submit( <any com.foo.common.message.PushMessage>, <any java.lang.String>, <any boolean> ); -> at com.foo.engine.push.MessageBroadcaster.submit(MessageBroadcaster.kt:224) Actual invocations have different arguments: messageBroadcaster.submit( {"id":"1","event":"test"}, "com.foo.engine" );
自定义any函数说明
我用以下自定义any函数解决Mockito与Kotlin配合时的“any不能为null”问题:
private fun <T> any(type: Class<T>): T = Mockito.any(type)
解决方案
问题核心在于@JvmOverloads和Kotlin默认参数的编译逻辑:
- Kotlin调用该方法不传第三个参数时,实际会编译为传入默认值
false的三参数调用; - Mockito校验时会识别方法的完整参数列表(三个参数),因此必须提供三个匹配器,不能只传两个;
- 第二次测试用
any(Boolean::class.java)会匹配任意Boolean值,但实际调用传入的是固定的false,导致参数不匹配。
正确做法是用eq(false)匹配第三个参数的默认值:
verify(service.messageBroadcaster, times(1)) .submit(any(PushMessage::class.java), any(String::class.java), eq(false))
如果测试场景允许忽略第三个参数的具体值,也可以使用anyBoolean()(需确保和自定义any函数兼容),但匹配实际传入的默认值false是更严谨的方式。
内容的提问来源于stack exchange,提问作者Jeffrey Blattman
相关产品推荐
相关产品推荐

