👻

mockkでprivate関数の引数にanyを指定したいとき

2022/10/28に公開

private関数をモック化する

MockkTest.kt
class User(
    private val name: String
) {
    fun greet(word: String) = this.hello(word)

    private fun hello(word: String): String {
        val hello = "Hello, $name.\n"
        return hello + word
    }
}

internal class MockkTest : FunSpec({
    test("test hello mock") {
        val user = spyk(User("yamanaka"), recordPrivateCalls = true)
        every { user["hello"]("word") } returns "mock private function"

        user.greet("word") shouldBe "mock private function"
    }
})
  • 対象のクラスインスタンスをspykで作成する。
  • recordPrivateCalls = trueを指定する。
  • every { <モック対象変数>["private関数名"](引数)}の形式でprivate関数をモック化する。

private関数にanyを指定する

MockkTest.kt
class User(
    private val name: String
) {
    fun greet(word: String) = this.hello(word)

    private fun hello(word: String): String {
        val hello = "Hello, $name.\n"
        return hello + word
    }
}

internal class MockkTest : FunSpec({
    test("test hello mock2") {
        val user = spyk(User("yamanaka"), recordPrivateCalls = true)
        every { user["hello"](any()) } returns "mock private function"

        user.greet("word") shouldBe "mock private function"
    }
})

これでうまくいきそうだけどこれだとエラーになる

対策

MockkTest.kt
class User(
    private val name: String
) {
    fun greet(word: String) = this.hello(word)

    private fun hello(word: String): String {
        val hello = "Hello, $name.\n"
        return hello + word
    }
}

internal class MockkTest : FunSpec({
    test("test hello mock3") {
        val user = spyk(User("yamanaka"), recordPrivateCalls = true)
        every { user["hello"](allAny<String>()) } returns "mock private function"

        user.greet("word") shouldBe "mock private function"
    }
})

any()ではなくallAny<String>()を指定することでうまく動作する。

以上!

GitHubで編集を提案

Discussion