MockK使用mockkStatic模拟带泛型顶层扩展方法报类型推断错误
运行环境
- MockK 版本:1.12.4
- Kotlin 版本:1.6
问题复现
在Extentions.kt中定义了不属于任何类的顶层泛型扩展方法,代码如下:
fun <T> Entity.selectReferenceAsSingleObject(referenceName: String): T { return this.selectReferencesByName(referenceName).single().asObjet() as T }
尝试使用mockkStatic模拟该方法时,初始写法为:
mockkStatic(Entity::selectReferenceAsOptionalSingleObject)
编译阶段抛出如下错误:
Not enough information to infer type variable T
错误根因是编译器无法推断待模拟方法的泛型类型参数T。
后续尝试了多种添加泛型参数的写法,均未生效:
mockkStatic<KFunction<MyType>>(Entity::selectReferenceAsSingleObject) mockkStatic<MyType>(Entity::selectReferenceAsSingleObject) mockkStatic(Entity<KFunction<MyType>>::selectReferenceAsSingleObject) mockkStatic(Entity<MyType>::selectReferenceAsSingleObject) mockkStatic(Entity::<KFunction<MyType>>selectReferenceAsSingleObject) mockkStatic(Entity::<MyType>selectReferenceAsSingleObject) mockkStatic(Entity::selectReferenceAsSingleObject<KFunction<MyType>>) mockkStatic(Entity::selectReferenceAsSingleObject<MyType>) mockkStatic(Entity::selectReferenceAsSingleObject as KFunction<MyType>) mockkStatic(Entity::selectReferenceAsSingleObject as MyType)
以上写法要么持续抛出类型推断错误,要么提示对应语法位置不允许使用类型参数,IDE也未提供正确的语法提示。
可行解决方案
Kotlin顶层函数编译后会生成名为[文件名]Kt的字节码类,函数作为该类的静态方法存在,不需要在mockkStatic阶段传入带泛型的方法引用,分两步处理即可:
- 传入顶层函数所在文件对应的编译类,完成静态mock注册:
// 如果你的文件名为Extentions.kt,对应生成的字节码类就是ExtentionsKt mockkStatic(ExtentionsKt::class) - 编写桩代码时,在方法调用处明确指定泛型类型即可:
// 将MyType替换为实际需要模拟的返回类型 every { any<Entity>().selectReferenceAsSingleObject<MyType>(any()) } returns 提前构造的MyType模拟返回实例
如果需要模拟多个不同返回类型的该泛型方法,只需要在桩代码阶段分别指定不同的泛型类型编写对应返回逻辑即可,不需要重复执行
mockkStatic。
内容的提问来源于stack exchange,提问作者Bradley Gray
相关产品推荐
相关产品推荐

