『@ParameterizedTest』1メソッドで複数のテストケースを実装!

Junitでテストを記述しているとインプットが違うだけで、結果やテスト内容が変わらないことがあります。

そういったときに1ケースに対して1テストメソッドを作るのは手間ですよね。。。

@ParameterizedTestを使えば対応できますよ!

@ParameterizedTestでできること

@ParameterizedTestを使わない場合はこんな感じのコードになりますよね。

    @Test
    public void sample1() {
        assertThat("a".length()).isEqualTo(1);
    }

    @Test
    public void sample2() {
        assertThat("b".length()).isEqualTo(1);
    }

(こんなテスト書かないですが、あくまでサンプルとして…)

@ParameterizedTestを使うとこうなります。

    @ParameterizedTest
    @ValueSource(strings = {"a", "b"})
    public void sample(String string) {
        assertThat(string.length()).isEqualTo(1);
    }

こんな感じで@ValueSourceの引数にパラメータを追加するだけで複数のテストをまとめることができます!

パラメータを指定する方法が何通りかあるのでご紹介します。

@ValueSource

  • 「パラメータが1つ」でかつ「型が基本型」の場合に使用する
  • パラメータの型によって引数の指定の仕方が変わる
  • @ValueSourceの引数で指定した値は、メソッドの引数で受け取る

基本型を一通り扱えるようなのですが、ここでは私がよく使うものにしぼってもう少し詳細に紹介します。

String

  • 空文字や空白文字は扱えるが、nullは扱えない
  • nullを扱いたい場合は後述の@MethodSourceを使用する
    @ParameterizedTest
    @ValueSource(strings = {"a", "b", "c"})
    public void string(String value) {
        System.out.println("string: " + value);
    }
string: 'a'
string: 'b'
string: 'c'
string: ''
string: '   '

int

    @ParameterizedTest
    @ValueSource(ints = {1, 2 ,3})
    public void ints(int value) {
        System.out.println("ints: " + value);
    }
ints: 1
ints: 2
ints: 3

@CsvSource

  • 複数のパラメータをメソッドに渡したい時に使用する
  • パラメータは文字列で記述し、Csvの名前の通りカンマ区切りで複数のパラメータを結合する
  • 数値を指定した場合はStringでもintでも受け取れる
    @ParameterizedTest
    @CsvSource({"1, val1", "2, val2", "3, val3"})
    public void csv(int num, String value) {  // 数値をintで受け取る
        System.out.println("num: '" + num + "', value: '" + value + "'");
    }
    @ParameterizedTest
    @CsvSource({"1, val1", "2, val2", "3, val3"})
    public void csv(String num, String value) {  // 数値をStringで受け取る
        System.out.println("num: '" + num + "', value: '" + value + "'");
    }
num: '1', value: 'val1'
num: '2', value: 'val2'
num: '3', value: 'val3'

  • nullや空文字も扱える
  • デフォルトだと前後の空白文字はトリミングされるが、”で囲むことで前後の空白文字も残せる
    @ParameterizedTest
    @CsvSource({"空文字, ''", "空白文字, '   '", "null, "})
    public void csv(String type, String value) {
        System.out.println(type + ": '" + value + "'");
    }
空文字: ''
空白文字: '   '
null: 'null'

@EnumSource

  • enumクラスの定義を元にテストを行いたい時に使える
  • namesmodeを指定するとinclue,excludeとかができる
  • modeのデフォルトはINCLUDE
    enum SampleEnum {
        ENUM1,
        ENUM2,
        ENUM3
    }
    @ParameterizedTest
    @EnumSource(SampleEnum.class)
    public void enumSource(SampleEnum value) {
        System.out.println("enum: " + value);
    }
enum: ENUM1
enum: ENUM2
enum: ENUM3
    @ParameterizedTest
    @EnumSource(value = SampleEnum.class, names = {"ENUM1", "ENUM2"})
    public void enumInclude(SampleEnum value) {
        System.out.println("enum: " + value);
    }
enum: ENUM1
enum: ENUM2
    @ParameterizedTest
    @EnumSource(value = SampleEnum.class, names = {"ENUM1", "ENUM2"}, mode = EnumSource.Mode.EXCLUDE)
    public void enumExclude(SampleEnum value) {
        System.out.println("enum: " + value);
    }
enum: ENUM3

@MethodSource

  • 任意のクラスを引数に渡せる
  • 引数に渡すためにStream, Iterable, Iteratorのいずれかを返り値とするstaticメソッドを定義する
  • 前述の通り、nullも扱える
    @ParameterizedTest
    @MethodSource("source")
    public void methodSource(String value) {
        System.out.println("value: " + value);
    }

    public static Stream<String> source() {
        return Stream.of("string1", "string2", null);
    }
value: string1
value: string2
value: null

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です