1. 序章

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

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

2. 設定

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

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.3.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

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

3. MockitoKotlinの使用

テストしたい実装があるとします– 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)

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

次に、このモックされたインスタンスをインスタンス化中に 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の本の在庫があるかどうかを尋ねられたときに、 told mockBookServicefalseを返すことに注意してください。 これにより、 checkout()呼び出しがIllegalStateExceptionをスローするはずです。

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

4. Mockito Kotlinライブラリ

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()メソッドも提供します。 このメソッドを使用する場合、型推論を活用できるため、追加のパラメーターを渡さずにメソッドを呼び出すことができます。

最後に、このライブラリは、Mockitoのネイティブwhen()メソッドを使用する場合のようにバックティックを必要とせずに、自由に使用できる新しいeverything()メソッドを公開します。

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

5. 結論

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

いつものように、GitHubリポジトリで完全なソースを確認できます。