如何在测试中使用Mockito或PowerMock模拟Kotlin扩展功能?因为它们是静态解析的,它们应该作为静态方法调用还是作为非静态方法进行测试?
答案 0 :(得分:4)
首先,Mockito知道没有 Kotlin特定的语言结构。最后,Mockito将看一下进入字节代码。 Mockito只能理解它在那里发现的内容以及看起来像Java语言结构的内容。
含义:确实,您可能希望使用javap来反汇编已编译的类文件,以识别要模拟的方法的确切名称/签名。
显然:当该方法是 static 时,你必须使用PowerMock或JMockit;如果没有,你应该更喜欢与Mockito。
从Java的角度来看,你只是避免模仿静态的东西;当然,事情变得非常有趣,现在不同的语言和不同的想法/概念汇集在一起。
答案 1 :(得分:4)
我认为 MockK 可以为您提供帮助。
它也支持模拟扩展功能。
您可以使用它来模拟对象范围的扩展:
data class Obj(val value: Int)
class Ext {
fun Obj.extensionFunc() = value + 5
}
with(mockk<Ext>()) {
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
}
如果扩展名是模块范围的,这意味着它是在文件中声明的(不在class
内),则应采用以下方式对其进行模拟:
data class Obj(val value: Int)
// declared in File.kt ("pkg" package)
fun Obj.extensionFunc() = value + 5
mockkStatic("pkg.FileKt")
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
通过在声明扩展名的包和文件的名称中添加mockkStatic("pkg.FileKt")
行(在示例中为pkg.File.kt
)。
答案 2 :(得分:2)
实例扩展功能可以在mockito-kotlin的帮助下进行存根和验证:
data class Bar(thing: Int)
class Foo {
fun Bar.bla(anotherThing: Int): Int { ... }
}
val bar = Bar(thing = 1)
val foo = mock<Foo>()
with(foo) {
whenever(any<Bar>().bla(any()).doReturn(3)
}
verify(foo).apply {
bar.bla(anotherThing = 2)
}
答案 3 :(得分:0)
我使用 mockk 库。
对于扩展文件写java名称,像这样:
@file:JvmName(name = "ExtensionUtils")
package myproject.extension
...
为了快速编码,我创建了具有不同扩展模拟的文件:
object FastMock {
fun extension() = mockkStatic("myproject.extension.ExtensionUtils")
fun listExtension() = mockkStatic("myproject.extension.ListExtensionUtils")
}
在测试中调用:
FastMock.listExtension()
every { itemList.move(from, to) } returns Unit