DEV Community

kaede
kaede

Posted on • Edited on

Kotlin Springboot -- Part 17 usecase の UT で usecase のインスタンスを DI で作成する

前提知識

https://dev.to/kaede_io/kotlin-ji-chu-part-7-di-dependency-injection-kontenahenodeng-lu-shi-yong-k5g

Spring または Java の DI コンテナのアノテーション

UT は Unit Test, 単体テストのこと。


参考

https://mockk.io/

mockk 公式

Annotations の章にサンプルが有る


why

        val personPort = mockk<PersonPort>()
        val target = PersonsUsecase(personPort)
Enter fullscreen mode Exit fullscreen mode

これを毎回全ての関数に書くのを楽にするため

自動 DI コンテナ登録を Rest の実装だけではなく、Usecase の単体テストでもやりたかった


mockk の @InjectMockks と @Mockks を使う

k が 2 つな方を使う。mockito からも似た名前ででているが
こっちを気づかず使うとエラーになるので注意

class PersonsUsecaseTest {
    @InjectMockKs
    lateinit var target: PersonsUsecase
    @MockK
    lateinit var port: PersonPort
Enter fullscreen mode Exit fullscreen mode

フィールドインジェクションをする。

target というクラス内部のグローバル変数を
PersonUsecase クラスの型だけ指定して
中身は Null の状態で作る。

port も同様に、呼ばれた時に Mockk で作成されるように
中身を Null で PersonPort の型だけ指定する。


MockKAnnotations.init で作成して unmockkAll で破壊する

MockKAnnotations.init(this) をすると
Mockk のアノテーションがついているフィールドインジェクションが
全て中身を入れ始める。

   @Test
    fun `全てのPersonを取得する`() {
        MockKAnnotations.init(this)
        val persons = mockk<Persons>()
        every { port.getAllPersons() } returns persons
        val actual = target.getAllPersons()
        actual shouldBeEqualTo persons
        unmockkAll()
    }
Enter fullscreen mode Exit fullscreen mode

これで Mockk のアノテーションを走り、
この段階で port の偽物が作られ、
それを利用して usecase の偽物も作られる。

そして port や target、つまり usecase が使われる。

最後に unmockkAll() をする。
これで Mockk のアノテーションで作成された偽物や
偽物を利用して作られた本物が爆発四散する。アイエエ!!!

なお、MockKAnnotations.init(this) が走るタイミングで
すでに偽物たちが作られていた場合は上書きされるので
最後の unmockkAll() は要らないかも知れない。

Top comments (0)