在Kotlin中模拟扩展功能

时间:2017-06-06 06:11:52

标签: unit-testing mocking mockito kotlin powermock

如何在测试中使用Mockito或PowerMock模拟Kotlin扩展功能?因为它们是静态解析的,它们应该作为静态方法调用还是作为非静态方法进行测试?

4 个答案:

答案 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)。

更多信息可在此处找到:web sitegithub

答案 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