26

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

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


你好世界.kt

fun sayHello() = "Hello Kotlin!"
4

5 回答 5

29

有办法模拟一个顶级函数:

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

你只需要知道这个函数去哪个文件。签入 JAR 或堆栈跟踪。

于 2018-10-19T14:44:46.467 回答
19

以下语法对我有用。

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

我很惊讶目前还没有任何东西jvm-stdlib

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

mockkStatic(::sayHello)
于 2020-10-30T10:23:14.957 回答
4

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

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

其中 mockStatic 将“package_name:class_file_name”作为参数但是为了简化 mockStatick 调用,您可以直接在文件中使用 @file:JvmName 为您的文件命名。

你好世界.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

于 2020-06-05T08:46:01.243 回答
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")
    }
}

这样做的问题是您更改生产代码只是为了迎合测试,而且感觉很做作。

于 2018-10-19T13:03:03.990 回答
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())
    }
}
于 2021-04-22T10:00:09.697 回答