Mockito Mocks表现得像间谍一样:Kotlin

时间:2017-10-11 16:59:04

标签: junit mockito kotlin

我在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

实际发生了什么<{1}}设置模拟方法正在调用底层函数,导致wheneverNullPointerException尝试阅读mapper时(当然为空)。

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

我已经能够通过memberFunction我试图模仿ClassFromAnotherLibrary而不是我的模拟来解决与此类似的问题,但是

  1. 感觉hacky,
  2. 在这种情况下不是一个选项(它不是我的课程来编辑,它来自另一个图书馆)
  3. 作为参考,这些是我的项目使用的相关gradle依赖项:

    interface

    我还在我的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" 文件夹中设置了MockMaker文件以启用test/resources,但我并不完全明白它可以实现的目标(看了一下提示)关于它here

    感谢任何Kotlin / Mockito

1 个答案:

答案 0 :(得分:2)

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