11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SpringMockKを使ってみた

Last updated at Posted at 2019-05-11

kotlinのmockライブラリで有名なMockK。便利ですよね。
MockitoのようにSpringに対応してくれればもっと便利なのになあと思っていたら、SpringMockKというそのものずばりなライブラリがあったので試してみました。

準備

Spring Initializrで作ったひな型に以下のようなサービスを追加します。
テストではこのサービスをmockにします。

HogeService.kt
package com.example.demo.service

import org.springframework.stereotype.Service

@Service
class HogeService {

    fun hoge() = "HogeService.hoge()"

    fun fuga() = "HogeService.fuga()"
}

また、HogeServiceを利用するコンポーネントも作成します。

Main.kt
package com.example.demo

import com.example.demo.service.HogeService
import org.springframework.stereotype.Component

@Component
class Main(
    private val hogeService: HogeService
) {

    fun main() = "${hogeService.hoge()}, ${hogeService.fuga()}"
}

build.gradleのdependenciesに以下を追加します。
com.ninja-squad:springmockkだけでなくnet.bytebuddy:byte-buddyも追加しないと動きませんでした。

build.gradle
dependencies {
    // ...略...
    // SpringMockK
	testImplementation 'net.bytebuddy:byte-buddy:1.9.12'
	testImplementation 'com.ninja-squad:springmockk:1.1.2'
    // ...略...
}

MockkBean

以下のようにmock化したいサービスに@MockkBeanアノテーションを付与するとよしなにmock化してくれます。
ちゃんとverifyもできますね。

SpringMockKTest.kt
package com.example.demo.service

import com.example.demo.Main
import com.ninjasquad.springmockk.MockkBean
import io.mockk.every
import io.mockk.verify
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension

@ExtendWith(SpringExtension::class)
@SpringBootTest
class SpringMockKTest {

    @MockkBean
    private lateinit var hogeService: HogeService

    @Autowired
    private lateinit var main: Main

    @Test
    fun mainTest() {
        every { hogeService.hoge() } returns "SpringMockKHoge.hoge()"
        every { hogeService.fuga() } returns "SpringMockKHoge.fuga()"

        assertEquals("SpringMockKHoge.hoge(), SpringMockKHoge.fuga()", main.main())

        verify {
            hogeService.hoge()
            hogeService.fuga()
        }
    }
}

SpykBean

@SpykBeanアノテーションでspyもできます。

SpringMockKSpyTest.kt
package com.example.demo.service

import com.example.demo.Main
import com.ninjasquad.springmockk.MockkBean
import com.ninjasquad.springmockk.SpykBean
import io.mockk.every
import io.mockk.verify
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension

@ExtendWith(SpringExtension::class)
@SpringBootTest
class SpringMockKSpyTest {

    @SpykBean
    private lateinit var hogeService: HogeService

    @Autowired
    private lateinit var main: Main

    @Test
    fun mainTest() {
        every { hogeService.hoge() } returns "SpringMockKHoge.hoge()"

        assertEquals("SpringMockKHoge.hoge(), HogeService.fuga()", main.main())

        verify {
            hogeService.hoge()
            hogeService.fuga()
        }
    }
}

おまけ

SpringMockKを利用せずにSpringでMockKを利用したい場合、以下の方法があるようです。
ただし、うまく動くのはバージョンが2.0.9.RELEASEまでで、Spring Initializrで生成したバージョン2.1.4.RELEASEではエラーで動きませんでした。

MockKTest.kt
package com.example.demo.service

import com.example.demo.Main
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.test.context.junit.jupiter.SpringExtension

// Springのバージョンが2.0.9.RELEASE までなら動く
@ExtendWith(SpringExtension::class)
@SpringBootTest
class MockKTest {

    @TestConfiguration
    class MockKConfig {

        @Bean
        fun hogeService() = mockk<HogeService>()
    }

    @Autowired
    private lateinit var hogeService: HogeService

    @Autowired
    private lateinit var main: Main

    @Test
    fun mainTest() {
        every { hogeService.hoge() } returns "MockKHoge.hoge()"
        every { hogeService.fuga() } returns "MockKHoge.fuga()"

        assertEquals("MockKHoge.hoge(), MockKHoge.fuga()", main.main())

        verify {
            hogeService.hoge()
            hogeService.fuga()
        }
    }
}

参考

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?