Mockito 4.11.0可变参数变更致测试失败,如何正确测试可变参数方法?
Mockito 4.11.0升级后Kotlin可变参数测试匹配失败解决方案
问题背景
升级Mockito到4.11.0版本后,涉及Kotlin可变参数(vararg)的单元测试出现参数匹配失败问题。无论是在verify中用arrayOf(arg1)还是直接传arg1,均提示参数不匹配,但相同代码在Mockito 4.10.0中可正常运行。
被测代码
package com.xyz.packagexyz open class TestService { fun doSomethingElse(message: String, vararg args: Any) { print("message: $message, args: $args") } } class TestClass(val service: TestService) { fun doSomething(message: String, vararg args: Any) { service.doSomethingElse(message, args) } }
原失败测试代码
internal class TestClassTest { private val mockService = mock<TestService>() private val testClass = TestClass(mockService) @Test fun test() { val message = "message" val arg1 = "arg1" testClass.doSomething(message, arg1) verify(mockService).doSomethingElse(message, arrayOf(arg1)) // 改用 verify(mockService).doSomethingElse(message, arg1) 仍失败 } }
正确解决方法
方案1:修正被测代码的可变参数传递逻辑
Kotlin中,将vararg参数直接传给另一个带vararg的方法时,必须使用展开操作符*——否则会把整个数组作为单个元素传入目标方法的可变参数列表。修正后的TestClass代码:
class TestClass(val service: TestService) { fun doSomething(message: String, vararg args: Any) { service.doSomethingElse(message, *args) // 添加*展开数组 } }
此时测试可直接使用直观的写法通过:
verify(mockService).doSomethingElse(message, arg1)
方案2:匹配实际传入的参数结构
若暂时无法修改被测代码,需要匹配实际调用时的嵌套数组结构:
verify(mockService).doSomethingElse(message, arrayOf(arrayOf(arg1)))
也可使用Mockito参数匹配器实现灵活匹配:
verify(mockService).doSomethingElse(eq(message), any())
问题根源
Mockito 4.11.0对Kotlin可变参数的匹配逻辑进行了严格化调整,不再兼容未用*展开的数组传递场景;而4.10.0版本的匹配逻辑相对宽松,导致错误的参数传递也能通过测试。
其他说明
目前可通过回退到Mockito 4.10.0或采用上述方案临时解决问题,该兼容性问题已提交至官方仓库跟进。
内容的提问来源于stack exchange,提问作者Zach
相关产品推荐
相关产品推荐

