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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:33:19