Mockitoとコトリン

モトキートとコトリン

1. 前書き

KotlinとJavaは手をつないで歩きます。 これは、Kotlinプロジェクトに存在する膨大な数のJavaライブラリを活用できることを意味します。

この短い記事では、KotlinでMockitoを使用してモックを作成する方法を説明します。 ライブラリについて詳しく知りたい場合は、check this article.

2. セットアップ

まず、Mavenプロジェクトを作成し、pom.xml:JUnitMockitoの依存関係を追加しましょう。


    org.mockito
    mockito-all
    2.0.2-beta
    test


    junit
    junit
    4.12
    test

また、ソースコードをコンパイルするためにKotlinを使用していることをMavenに通知する必要があります。 pom.xmlで構成する方法の詳細については、official Kotlin documentationを確認してください。

3. KotlinMockitoを使用する

テストしたい実装があるとします–LendBookManager.このクラスは、まだ実装されていないBookServiceと呼ばれるサービスに依存しています。

interface BookService {
    fun inStock(bookId: Int): Boolean
    fun lend(bookId: Int, memberId: Int)
}

BookServiceは、LendBookManagerのインスタンス化中に注入され、checkoutメソッド全体で2回使用されます。これは、次のテストを作成するために必要なメソッドです。

class LendBookManager(val bookService:BookService) {
    fun checkout(bookId: Int, memberId: Int) {
        if(bookService.inStock(bookId)) {
            bookService.lend(bookId, memberId)
        } else {
            throw IllegalStateException("Book is not available")
        }
    }
}

BookServiceをモックする機能がなければ、そのメソッドの単体テストを作成するのは難しいでしょう。これは、Mockitoが役立つところです。

たった2行のコードで、BookServiceインターフェースのモックを作成し、inStock()メソッドが呼び出されたときに固定値を返すように指示できます。

val mockBookService = Mockito.mock(BookService::class.java)
Mockito.`when`(mockBookService. inStock(100)).thenReturn(true)

これにより、引数100でinStock()メソッドが呼び出されるたびにmockBookServiceインスタンスがtrueを返すように強制されます(バッククォートを使用してwhen()メソッドをエスケープする必要があることに注意してください。これwhenはKotlin言語ではreserved keywordであるため、が必要です)。

次に、インスタンス化中にこのモックされたインスタンスをLendBookManagerに渡し、テストするメソッドを呼び出し、操作の結果としてlend()メソッドが呼び出されたことを確認できます。

val manager = LendBookManager(mockBookService)
manager.checkout(100, 1)
Mockito.verify(mockBookService).lend(100, 1)

メソッドの実装の他の論理パスをすばやくテストできます。目的の本が在庫にない場合は、例外がスローされます。

@Test(expected = IllegalStateException::class)
fun whenBookIsNotAvailable_thenAnExceptionIsThrown() {
    val mockBookService = Mockito.mock(BookService::class.java)
    Mockito.`when`(mockBookService. inStock(100)).thenReturn(false)
    val manager = LendBookManager(mockBookService)
    manager.checkout(100, 1)
}

このテストでは、ID 100の本の在庫があるかどうかを尋ねられたときに、toldmockBookServicefalseを返すことに注意してください。 これにより、checkout()呼び出しでIllegalStateExceptionがスローされます。

@Testアノテーションでexpectedプロパティを使用します。これは、このテストで例外がスローされることを示しています。

4. MockitoKotlinライブラリ

mockito-kotlinというオープンソースライブラリを使用することで、コードをKotlinのように見せることができます。 このライブラリは、Mockitoの機能の一部をメソッドにラップし、よりシンプルなAPIを提供します。

@Test
fun whenBookIsAvailable_thenLendMethodIsCalled() {
    val mockBookService : BookService = mock()
    whenever(mockBookService.inStock(100)).thenReturn(true)
    val manager = LendBookManager(mockBookService)
    manager.checkout(100, 1)
    verify(mockBookService).lend(100, 1)
}

また、mock()メソッドのバージョンも提供します。 このメソッドを使用すると、型推論を活用して、追加のパラメーターを渡さずにメソッドを呼び出すことができます。

最後に、このlibrary exposes a new whenever() method that can be used freely, without the need for back-ticks like we had to when using Mockito’s native when() method.

拡張機能の完全なリストについては、their wikiを確認してください。

5. 結論

このクイックチュートリアルでは、MockitoとKotlinを一緒に使用するようにプロジェクトをセットアップする方法と、この組み合わせを活用してモックを作成し、効果的な単体テストを作成する方法を確認しました。

いつものように、GitHub repoで完全なソースをチェックアウトできます。