1
1

More than 3 years have passed since last update.

【Android】JUnit5で複数の引数パターンに対しParameterized Testを行う

Posted at

概要

複数の引数を取り、組み合わせに応じて返す結果が何パターンもあるとき、
1つ1つテストを書いているとコード量が多くなってしまいます。
そこでParametrised Testを使います。
引数のパターン数だけ用意すれば、一つのメソッドをそのパターン数分だけテストしてくれる優れものです。

Android-Kotlinの単体テストにはJUnit5を使います。

JUnit5導入

build.gradle(トップレベル)

dependencies {
        classpath "de.mannodermaus.gradle.plugins:android-junit5:1.4.2.0"
}

build.gradle(app)

dependencies {
                testImplementation 'org.junit.jupiter:junit-jupiter:5.5.2'
                testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
                testImplementation 'org.junit.jupiter:junit-jupiter-params:5.5.2'
                testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
}

※注意: 自動でImportされないかも

私がJUnit5を試したときにはなぜかAndroidStudioに認識されずハマりました。。
Importを手動でやるとうまくいきます。
JUnit5の@ParameterizedTestがAndroidStudioで認識されない

テストを書く

REST APIを2つ叩いた結果を引数に加えて、使用可能な型リストを返すような関数:
UseCase.getSelectableTypeList() をテストします。

APIレスポンスはJSON形式で返ってくるのでダミーで作り、data classに変換します。

引数の組み合わせをselectableTestCaseとして定義しておき、テストで
@MethodSource("selectableTestCase")を呼び出します。

テスト内で受け取った引数をdata classのvalueと差し替えて、
関数の返り値が期待通りか判定します。

import com.google.gson.Gson
import com.google.gson.JsonIOException
import com.google.gson.JsonSyntaxException
import jp.ucs.cardApp.domain.entity.auth.HogeResponse
import org.junit.jupiter.api.Assertions.*
import java.io.InputStreamReader
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.Arguments.arguments
import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream


internal class HogeUseCase {
   // data class
    lateinit var hogeResponse: HogeResponse
    lateinit var fugaResponse: FugaResponse

    companion object {
        const val HOGE_JSON = "{\"id\":\"2\",\"id\":\"3k3k02k\",\"aaaIdFlg\":\"0\",\"hogeFlg\":\"0\",\"cccFlg\":\"0\",\"dddState\":\"0\"}"
        const val FUGA_JSON = "{\"beginingDate\":\"20211010\",\"endDate\":\"20210921\",\"hogeType\":\"2\",\"hogeNum\":\"0\",\"hogeAmount\":\"030\",\"fugaTypeFlg":\"0\",\"fugaAmount\":\"030\"}\n"

        @JvmStatic
        fun selectableTestCase(): Stream<Arguments> =
            Stream.of(
                // 引数の順番:fugaType id, hogeFlg, hogeType, fugaFlg, 期待値
                arguments(FugaType.BANANA, "2", "1", "1", "1", Type.A),
                arguments(FugaType.BANANA, "2", "0", "1", "1", Type.B),
                arguments(FugaType.BANANA, "2", "0", "2", "2", Type.C),
                arguments(FugaType.GORIRA, null, "0", "1", "1", Type.S),
                arguments(FugaType.GORIRA, null, "0", "2", "2", Type.G),
                arguments(FugaType.GORIRA, "1", "0", "1", "1", Type.S),
                arguments(FugaType.GORIRA, "1", "0", "2", "2", Type.ELSE),
                arguments(FugaType.GORIRA, "2", "0", "1", "1", Type.S),
                arguments(FugaType.GORIRA, "2", "0", "2", "2", Type.ELSE),
            )
    }

    @org.junit.jupiter.api.BeforeEach
    fun setUp() {
        // JSONをdata classにしておく
        try {
            hogeResponse = Gson().fromJson(
                HOGE_JSON,
                HogeResponse::class.java
            )
            fugaResponse = Gson().fromJson(
                FUGA_JSON,
                FugaResponse::class.java
            )
        } catch (e: JsonSyntaxException) {
            e.printStackTrace()
        } catch (e: JsonIOException) {
            e.printStackTrace()
        } finally {
        }
    }

// 予め定義しておいた引数たちをMethodSourceアノテーションで呼び出す
// 引数の数分このテストを回してくれる
    @ParameterizedTest
    @MethodSource("selectableTestCase")
    fun getSelectableTypeList(
        fugaType: FugaType,
        id: String?,
        hogeFlg: String,
        hogeType: String,
        fugaFlg: String,
        expectedValue: List<Type>
    ) {
        Pair(hogeResponse, fugaResponse).let {
            val actual = UseCase.getSelectableTypeList(
                fugaType,
                // ダミーのdata classの中身を差し替える
                it.first.copy(id = id, hogeFlg = hogeFlg),
                it.second.copy(hogeType = hogeType, fugaFlg = fugaFlg)
            )
            assertEquals(expectedValue, actual)
        }
    }
1
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
1
1