JUnit5の試験実装３パターン比較

久しぶりに新規のJavaプロジェクトを立ち上げる。  
テストコードについて今から立ち上げるプロジェクトでSpockを選択というのはコミュニティがEclipse捨てた背景から開発環境に制限をかけるようでちょっとな〜という気持ち。  
JUnit５ベースにどうか書けばいいか、パラメータテストをどう実装できるのか確認していく。


## 試験対象
処理はなんだっていいので値を２つ受け取って文字列をくっつけるだけの雑なものを用意する。
```java
package com.batch.demo.base.util;

public class TextUtils {

    /**
     * 渡された２つの文字列を結合する
     * @param firstText １つ目の文字列
     * @param secondText２つ目の文字列
     * @return 結合した文字列
     */
    public String mixTwoText(String firstText, String secondText) {
        return firstText + secondText;
    }
}

```

# 試験パターンの統一
以下の試験パターンを共通して実装して、コード量や結果の見え方を確認していく。
- `aaa` と `XXX`　を渡すと `aaaXXX` が返却されること
- `bbb` と `XXX`　を渡すと `bbbXXX` が返却されること
- `ccc` と `XXX`　を渡すと `cccXXX` が返却されること

## 通常のJUnit5
```java
package com.batch.demo.base.util;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class TextUtilsTest {

    @Test
    void TextMixTestCase1(){
        String first = "aaa";
        String second = "XXX";
        TextUtils textUtils = new TextUtils();
        String result = textUtils.mixTwoText(first, second);
        Assertions.assertEquals("aaaXXX", result);
    }
    @Test
    void TextMixTestCase2(){
        String first = "bbb";
        String second = "XXX";
        TextUtils textUtils = new TextUtils();
        String result = textUtils.mixTwoText(first, second);
        Assertions.assertEquals("bbbXXX", result);
    }
    @Test
    void TextMixTestCase3(){
        String first = "ccc";
        String second = "XXX";
        TextUtils textUtils = new TextUtils();
        String result = textUtils.mixTwoText(first, second);
        Assertions.assertEquals("cccXXX", result);
    }
}
```

うーん、なんか古臭い・・・



## TestParameterInjector
[TestParameterInjector](https://github.com/google/TestParameterInjector)というGoogleがJavaのテストで利用しているというテストライブラリを試してみる。

```java
package com.batch.demo.base.util;

import com.google.testing.junit.testparameterinjector.junit5.TestParameter;
import com.google.testing.junit.testparameterinjector.junit5.TestParameterInjectorTest;
import org.junit.jupiter.api.Assertions;

public class TextUtilsTest {
    protected enum TextMixTestCase {
        Case1("aaa","XXX","aaaXXX"),
        Case2("bbb","XXX","bbbXXX"),
        Case3("ccc","XXX","cccXXX");

        private String first;
        private String second;
        private String answer;
        private TextMixTestCase(String first, String second, String answer) {
            this.first = first;
            this.second = second;
            this.answer = answer;
        }
    }
    @TestParameterInjectorTest
    void test1(@TestParameter TextMixTestCase textMixTestCase) {
        TextUtils textUtils = new TextUtils();
        Assertions.assertEquals(textUtils.mixTwoText(textMixTestCase.first,textMixTestCase.second), textMixTestCase.answer);
    }
}
```

うーん、いいらしいという雰囲気に惑わされただけかな。  
enumが面倒だ。。

## JUnit5のParameterizedTest
```java
package com.batch.demo.base.util;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

public class TextUtilsTest {
    @ParameterizedTest
    @CsvSource({
            "aaa,  XXX,  aaaXXX",
            "bbb,  XXX,  bbbXXX",
            "ccc,  XXX,  cccXXX",
    })
    void paramTestJunit(String first, String second, String answer) {
        TextUtils textUtils = new TextUtils();
        Assertions.assertEquals(textUtils.mixTwoText(first, second), answer);
    }
}
```
一番スッキリしてる！！

# 締め
JUnit5のParameterizedTestでパラメータをCsvSourceで指定して試験を実施できるのが一番スッキリしてる！  
このパラメータをテストクラスファイル内じゃなく外部CSVファイルとかJSONファイルとして外に持つこともできるんだろうか。。。。