如何在Kotlin中用Mockito模拟含vararg参数的bind方法?
解决Kotlin中Mockito/PowerMock模拟带vararg参数方法的问题
我之前也踩过这个坑——当vararg参数里混着不同类型的值时,Mockito的匹配器经常因为类型擦除或者参数匹配逻辑的问题,导致mock直接返回null。下面是几个亲测有效的解决方案:
1. 先修正Mock对象的声明方式
你当前把preparedStatement声明成了nullable的var类型,用?.做安全调用时,Mockito可能没法正确拦截这个方法调用。建议改成lateinit var配合@Mock注解,确保对象是一个非空的mock实例:
class DbSessionTest { @Mock lateinit var preparedStatement: PreparedStatement @Mock lateinit var boundStatement: BoundStatement @Before fun setup() { initMocks(this) // 后续mock逻辑写在这里 } }
2. 用mockito-kotlin的anyVararg()匹配器
anyVararg()是mockito-kotlin专门为可变参数设计的匹配器,能完美适配任意类型、任意长度的vararg参数。修改你的mock逻辑如下:
import com.nhaarman.mockito_kotlin.anyVararg import com.nhaarman.mockito_kotlin.whenever @Before fun setup() { initMocks(this) whenever(preparedStatement.bind(*anyVararg())).thenReturn(boundStatement) }
3. 用argThat强制匹配任意数组参数
如果anyVararg()还是不生效,可以用argThat自定义匹配逻辑,直接接受任何传入的数组参数:
import org.mockito.ArgumentMatchers.argThat @Before fun setup() { initMocks(this) whenever(preparedStatement.bind(argThat { true })).thenReturn(boundStatement) }
这里的argThat { true }表示不管数组里的元素是什么类型、有多少个,都匹配成功。
4. 如果你用了PowerMock,别忘了加必要注解
如果同时搭配PowerMock使用,得确保测试类添加了对应的注解,让PowerMock能正确处理类的字节码:
@RunWith(PowerMockRunner::class) @PrepareForTest(YourDbSessionClass::class) // 替换成你实际要测试的类 class DbSessionTest { // ... 测试代码 ... }
为什么之前的写法会失效?
当你传入混合类型的参数时,Kotlin会把vararg打包成Array<Any>类型的数组,但JVM层面可能因为类型擦除,实际数组类型变成了Array<Serializable>这类父类型。Mockito默认的any()如果没指定类型,会匹配单个Any对象而非数组;any<Array<Any>>()又可能因为实际类型不匹配而失效,这时候anyVararg()或者argThat就能绕过这个问题。
内容的提问来源于stack exchange,提问作者nathansizemore
相关产品推荐
相关产品推荐

