【问题标题】:Mockito Mocks Behaving Like Spies: KotlinMockito 模仿间谍行为:Kotlin
【发布时间】:2018-03-23 10:59:02
【问题描述】:

我正在开发一个 kotlin jar,我试图在其中模拟函数的输入

class MyService
fun serviceFunction(input: ClassFromAnotherLibrary): Output {
  val foo = input.memberFunction()

恰好memberFunction已通过包级扩展函数添加到我的包中的该类

fun ClassFromAnotherLibrary.memberFunction() : Foo {
  val mapper = jacksonObjectMapper()
  return mapper.readValue(this.serializedFoo, Foo::class.java)
}

现在我想为serviceFunction 编写一个测试,但我想模拟出memberFunction 调用(对此我有单独的测试)。

所以在我的 Mockito JUnit 测试中,我执行以下操作

val service = Service()
val mockClassFromAnotherLibrary = mock<ClassFromAnotherLibrary>()
val mockFoo = mock<Foo>()

whenever(mockClassFromAnotherLibrary.memberFunction())
  .thenReturn(mockFoo)

service.serviceFunction(mockClassFromAnotherLibrary)

我希望memberFunction 的实际实现永远不会被调用,并且我的模拟会拦截任何调用它的尝试并返回我的mockFoo

实际上发生的是 whenever 设置来模拟方法正在调用底层函数,当mapper 尝试读取时导致NullPointerException serializedFoo(当然是 null)。

我的问题是:到底为什么真正的 memberFunction 会被执行? 我是 Mockito 和 Kotlin 的新手,但我使用过 Jasmine(用于 JS)和 Spock(用于 Groovy / Java)过去的测试,并在这两个框架中模拟出一个对象永远不会真正执行任何模拟出的函数(我知道)。

我过去可以通过使我尝试模拟的ClassFromAnotherLibrary 有一个我模拟的interface 来解决与此类似的问题,但是

  1. 感觉很老套,而且
  2. 在这种情况下不是一个选项(这不是我要编辑的课程,它来自另一个库)

作为参考,这些是我的项目正在使用的相关 gradle 依赖项:

compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.8.9"
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.9"
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.9"

testCompile 'junit:junit:4.12'
testCompile "org.jetbrains.kotlin:kotlin-test:1.1.4-3"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:1.1.4-3"
testCompile "com.nhaarman:mockito-kotlin:1.3.0"
testCompile "org.mockito:mockito-inline:2.8.47"

我还在我的test/resources 文件夹中设置了一个MockMaker 文件以启用mock-maker-inline,尽管我并不完全理解它可能会完成什么(看到了关于它的提示here

感谢 Kotlin/Mockito

【问题讨论】:

    标签: junit mockito kotlin


    【解决方案1】:

    扩展函数只不过是一个常规的 Java 静态方法,据我所知,Mockito 不能模拟静态方法。

    【讨论】:

    • 您是说 Kotlin 扩展函数(可以访问 this)在底层实现为类静态函数?这是否意味着它也有一个隐含的论点(this)?我不知道 Mockito 不能模拟静态方法,很高兴知道!
    • 是的。就是这样。
    • 感谢您指出这一点!对于其他不想相信 Rafal 的话的人(我总是喜欢有多个来源),这里有一篇解释:android.jlelse.eu/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    • 2017-07-12
    相关资源
    最近更新 更多