Mockk允许模拟静态函数,但是如何模拟Kotlin顶级函数呢?
例如,如果我有一个名为HelloWorld.kt
的Kotlin文件,该如何模拟sayHello()
函数?
HelloWorld.kt
fun sayHello() = "Hello Kotlin!"
答案 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())
}
}