您如何模拟Kotlin顶级功能?

时间:2018-10-19 10:48:44

标签: kotlin mockk

Mockk允许模拟静态函数,但是如何模拟Kotlin顶级函数呢?

例如,如果我有一个名为HelloWorld.kt的Kotlin文件,该如何模拟sayHello()函数?


HelloWorld.kt

fun sayHello() = "Hello Kotlin!"

5 个答案:

答案 0 :(得分:8)

有一种方法可以模仿顶级功能:

mockkStatic("pkg.FileKt")
every { fun() } returns 5

您只需要知道此功能转到哪个文件即可。检入JAR或堆栈跟踪。

答案 1 :(得分:3)

要添加以前的答案,这是可行的:

mockkStatic("pkg.FileKt")
every { fun() } returns 5

mockStatic作为参数“ package_name:class_file_name” 但是为了简化对嘲笑状态的调用,您可以直接在文件中使用@file:JvmName为文件指定编译器名称。

HelloWorld.kt

@file:JvmName("hello")
fun sayHello() = "Hello Kotlin!"

HelloWorldTest.kt

mockkStatic("pkg.hello")
every { fun() } returns 5

更详细地说明了为什么需要这样做以及此处的其他示例:https://blog.kotlin-academy.com/mocking-is-not-rocket-science-mockk-advanced-features-42277e5983b5

答案 2 :(得分:1)

以@Sergey的答案为基础:

您可以在一个变量中实现sayHello()函数的实际实现,该变量然后是sayHello()函数参数的默认值。

此示例有效:

package tests

import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test

val sayHelloKotlin = { "Hello Kotlin!" }
fun sayHello(producer: () -> String = sayHelloKotlin): String = producer()

class Tests {
    interface Producer {
        fun produce(): String
    }

    @Test
    fun `Top level mocking`() {
        val mock = mockk<Producer>()
        every { mock.produce() } returns "Hello Mockk"

        val actual = sayHello(mock::produce)
        Assertions.assertEquals(actual, "Hello Mockk")
    }
}

这样做的问题是,您只是为了满足测试而更改生产代码,并且感觉很虚构。

答案 3 :(得分:1)

以下语法对我有用。

mockkStatic(::sayHello.javaMethod!!.declaringClass.kotlin)

我很惊讶jvm-stdlib上还没有任何东西。

编辑: 现在已正式引入了此重载: https://github.com/mockk/mockk/pull/518

mockkStatic(::sayHello)

答案 4 :(得分:0)

此代码不适用于我的 mockk 1.10.0 版,但在 1.11.0 中运行良好(当然需要更改 mockkStatic(::bar) )

实用工具.kt

@file:JvmName("UtilsKt")
package com.example.myapplication

fun foo(): Boolean {
  return bar()
}

fun bar():Boolean {
  return false
}

测试

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.O_MR1])
class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        mockkStatic("com.example.myapplication.UtilsKt")
        every { bar() } returns true
        assertTrue(foo())
    }
}