JUnit + Mockito テストケースを Kotest + MockK に書き換える
   1 min read

Kotest + MockK の組み合わせは Kotlin ではメジャー…​かと思いきや検索してみても公式の

にあるような例しか見つかりませんでした。 Mockito で言うところの @Mock@InjectMocks を使ってモックを差し込みたいんじゃい! ということでサンプルです。

前回の記事 Kotlin で JUnit4 のテストケースを書く のテストコードと同じものを作成しています。

前回のコードと見比べてみると分かる通り、結構似てます(差分)。

package com.github.yukihane.example

import io.kotest.core.spec.style.FunSpec
import io.kotest.datatest.withData
import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldBeSameInstanceAs
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.mockk

class MyControllerKtTest : FunSpec() {

    @MockK
    private lateinit var service: MyService

    @MockK
    private lateinit var outputMapper: MyParamMapper

    @InjectMockKs
    private lateinit var sut: MyController

    data class Param(val input: MyParamDTO, val expected: MyParamDTO)

    private val params = listOf(
        Param(
            MyParamDTO("alice", 16),
            MyParamDTO("alice", 17)
        ),
        Param(
            MyParamDTO("bob", 32),
            MyParamDTO("bob", 33)
        )
    )

    init {

        beforeTest {
            MockKAnnotations.init(this)
        }

        context("normal") {
            withData<Param>(nameFn = { "${it.input.name} ${it.input.age}" }, params) { param ->
                val service: MyService = MyServiceImpl()
                val controller = MyController(service, MyParamMapper.INSTANCE)
                val res = controller.index(param.input)
                res shouldBe param.expected
            }
        }

        context("mocking") {
            withData(nameFn = { "${it.input.name} ${it.input.age}" }, params) { param ->
                every { outputMapper.convert(any<MyParamDTO>()) } returns mockk()
                every { service.execute(any()) } returns mockk()
                val exp = mockk<MyParamDTO>()
                every { outputMapper.convert(any<MyParam>()) } returns exp

                val res = sut.index(param.input)
                res shouldBeSameInstanceAs exp
            }
        }
    }
}