web-dev-qa-db-ja.com

Kotlinラムダコールバックの単体テスト

テストする次の関数があるとしましょう

_fun loadData(dataId: Long, completion: (JsonElement?, Exception?) -> Unit) {
    underlayingApi.post(url = "some/rest/url",
            completion = { rawResult, exception ->
                val processedResult = processJson(rawResult)
                completion(processedResult, exception)
            })
}
_

underlayingApiの呼び出しをモック、インジェクト、スタブ、および検証する方法は明らかです。

返された結果を確認する方法completion(processedResult, exception)

15
Martin Mlostek

ラムダの動作をテストするには、このようにunderlayingApiオブジェクトを介してラムダが呼び出される場所でInvoactionOnMockをモックする必要があります。

    `when`(underlayingApi.post(eq("some/rest/url"),
                               any())).thenAnswer {
        val argument = it.arguments[1]
        val completion = argument as ((rawResult: String?, exception: Exception?) -> Unit)
        completion.invoke("result", null)
    }

これにより、テスト中のオブジェクト内でコールバックが呼び出されます。次に、テスト中のオブジェクトからのコールバックが機能しているかどうかを確認するには、そのように確認します。

    objUnderTest.loadData(id,
                          { json, exception ->
                              assert....
                          })
7
Martin Mlostek

マーティンの答えに基づいて、ここに糸くずの警告なしの私のアプローチがあります:

import com.nhaarman.mockito_kotlin.*

@Test
fun loadData() {
    val mockUnderlyingApi: UnderlayingApi = mock()
    val underTest = ClassBeingTested()
    underTest.underlayingApi = mockUnderlyingApi

    whenever(mockUnderlyingApi.post(eq("some/rest/url"), any())).thenAnswer {
        val completion = it.getArgument<((rawResult: String?, exception: Exception?) -> Unit)>(1)
        completion.invoke("result", null)
    }

    underTest.loadData(0L,
            { jsonElement, exception ->
                // Check whatever you need to check
                // on jsonElement an/or exception
            })
}
4
Sebastian