web-dev-qa-db-ja.com

どのようにしてコトリンのトップレベル関数をモックしますか?

Mockk は静的関数のモックを許可しますが、どのようにしてKotlinトップレベル関数をモックしますか?

たとえば、_HelloWorld.kt_という名前のKotlinファイルがある場合、sayHello()関数をモックするにはどうすればよいですか?


HelloWorld.kt

_fun sayHello() = "Hello Kotlin!"
_
11
Niel de Wet

トップレベルの関数をモックする方法があります:

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

この関数がどのファイルに移動するかを知る必要があるだけです。 JARまたはスタックトレースをチェックインします。

12
oleksiyp

@oleksiypの回答が機能します。次に例を示します。

HelloWorld.kt

package hello

fun sayHello() = "Hello Kotlin!"

Tests.kt

package hello

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

class Tests {
    @Test
    fun `Top level mocking`() {
        mockkStatic("hello.HelloWorldKt")
        every { sayHello() } returns "Hello Mockk"

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

残念ながら、これは私の現実の問題を解決しないため、私の元の質問は単純すぎるようです

3
Niel de Wet

@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")
    }
}

これの問題は、テストに対応するためだけに本番用コードを変更していることであり、不自然に感じられます。

1
Niel de Wet