Kotlin Mockk问题:无法正确Mock列表,验证shuffled调用报错
验证List.shuffled()调用时的MockK错误解决
问题分析
你遇到的类型转换错误和验证失效问题,核心原因有两个:
- Kotlin的
shuffled()是扩展函数而非List成员方法:直接在mockk<List<String>>中mockshuffled()是无效的,MockK默认无法拦截扩展函数的调用,这种错误的mock方式会导致内部类型转换异常。 - verify块的误用:直接在
verify中执行choiceList.take(6).shuffled()会触发实际调用,导致无论业务代码是否执行过该方法,验证结果都会显示为true。
解决方案
正确mock并验证shuffled扩展函数
使用MockK的mockkStatic方法来拦截扩展函数的调用,具体代码如下:
import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.spyk import io.mockk.verify fun testShuffledCall() { // 拦截kotlin.collections包下的扩展函数 mockkStatic("kotlin.collections.CollectionsKt") val mockList = mockk<List<String>>() val choiceList = spyk(listOf("String1", "String2")) { every { take(6) } returns mockList } // 指定mockList调用shuffled时的返回值 every { mockList.shuffled() } returns listOf("mock-shuffled-result") // 执行业务逻辑 val tmp = choiceList.take(6) val tmp2 = tmp.shuffled() // 验证shuffled确实被调用在mockList上 verify { mockList.shuffled() } }
关键说明
- mock扩展函数的类路径:JVM平台下
shuffled()属于kotlin.collections.CollectionsKt类,必须通过mockkStatic指定这个类才能拦截扩展函数调用。 - 避免verify块执行实际代码:验证时直接引用
mockList.shuffled(),而不是通过choiceList.take(6).shuffled(),后者会触发新的调用,导致验证结果失真。 - 解决类型转换错误:通过正确mock扩展函数,避免了原代码中mock代理对象被错误转换为Integer的问题,因为扩展函数的调用会被MockK正确拦截,不会执行到需要访问List内部方法的逻辑。
其他尝试的问题解释
- 将
choiceList改为mock无法解决问题:因为核心问题是shuffled是扩展函数,与choiceList是spy还是mock无关。 - 合并临时变量导致验证失效:本质是verify块中执行了
choiceList.take(6).shuffled(),触发了额外调用,导致验证结果不准确。
内容的提问来源于stack exchange,提问作者theresawalrus
相关产品推荐
相关产品推荐

