JUnitでCSVのテストをする方法

JUnitでCSVのテストをする方法

JUnitで@ParameterizedTestアノテーションをつけることによってCSVのテストが可能になります。

あと@Disabledを付けるとテストメソッドが無効化されます。

その他色々検証できるので簡単に纏めてみました。

@Disabledでテストメソッドの無効化

@Disabledをメソッドにつけるとそのテストコードを無効化することができます。クラスに対してもこのアノテーションはつけることができます。

package jp.co.test;

import static org.assertj.core.api.Assertions.assertThat;

import java.time.LocalDate;

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

public class MainTest {
  @Disabled
  @Test
  public void test1() {
    LocalDate ld = LocalDate.of(2019, 11, 13);
    assertThat(ld).isEqualTo(LocalDate.of(2019, 11, 13));
  }
}

この場合、JUnitビューでは以下のように表示されます。

JUnitのAssertJの使い方

パラメータ化テストメソッド

@ParameterizedTestアノテーションをつけると色んなパラメータを渡してテストすることが可能になります。CSVファイルをパラメータで渡すことも可能だったりします。

このアノテーションを使用するときは@Testアノテーションは不要です。

package jp.co.test;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class MainTest {
  @ParameterizedTest
  @ValueSource(strings = {"a", "bb", "ccc"})
  public void test1(String str) { // 3回実行される
    if(str.length() == 1) {
      assertThat(str).isEqualTo("a");
    } else if(str.length() == 2) {
      assertThat(str).isEqualTo("bb");
    } else {
      assertThat(str).isEqualTo("ccc");
    }
  }
}

stringsに限らず、intsなどいろいろ指定できます。

指定できる値
shorts
bytes
ints
longs
floats
doubles
chars
booleans
strings
classes

CSV検証

@CsvFileSourceアノテーションを使用すれば、CSVファイルの検証をすることが可能です。

パラメータ化テストメソッドである必要があります。

@CsvFileSource(resources = "sample.csv", numLinesToSkip = 1)

resourcesでcsvファイルを指定します。

numLinesToSkip = 1としてヘッダ行をスキップすることができます。省略すると0になります。

package jp.co.test;

import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;

public class MainTest {
  @ParameterizedTest
  @CsvFileSource(resources = "sample.csv", numLinesToSkip = 1)
  public void test1(String name, Integer age) { // 3回実行される
    assertNotNull(name); // nullではない
    assertNotEquals(0, age); // 0ではない
  }
}

Exception検証

例外のテストも実行することが可能です。

いくつか種類がありますが、assertThatIllegalArgumentExceptionの例です。

ここでは意図的にthrowしています。

package jp.co.test;

import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;

import org.junit.jupiter.api.Test;

public class MainTest {
  @Test
  public void test1() {
    assertThatIllegalArgumentException().isThrownBy(() -> {
      throw new IllegalArgumentException("message");
    }).withMessage("message");
  }
}

以下はassertThatExceptionOfTypeを使用した例です。引数にIndexOutOfBoundsExceptionなどの例外クラスを指定するとそのテストができます。

package jp.co.test;

import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

import java.util.Arrays;
import java.util.List;

import org.junit.jupiter.api.Test;

public class MainTest {
  @Test
  public void test1() {
    assertThatExceptionOfType(IndexOutOfBoundsException.class).isThrownBy(() -> {
      List<String> list = Arrays.asList("a", "b");
      list.get(3);
    }).withMessage("3"); // OK
  }
}

containsOnlyで配列やリストの要素を検証

containsOnlyを使って配列の中身が全て一致するかどうかを検証することができます。

package jp.co.test;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Emp {
  private String name;
  private Integer age;
}

上記のクラスのフィールドが一致しているかを確認します。(nameとageだけか検証)

package jp.co.test;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Arrays;

import org.junit.jupiter.api.Test;

public class MainTest {
  @Test
  public void test1() {
    String[] fields = {"age","name"}; // POJOのフィールド名
    String[] expect = Arrays.stream(Emp.class.getDeclaredFields())
      .map(r -> r.getName())
      .toArray(String[]::new);
    assertThat(fields).containsOnly(expect);
  }
}

配列で検証しましたがリストなどのコレクションでもテストできます。要素の順序は検証に関係ありません。

containsExactlyで配列やリストの要素を検証

containsExactlyはcontainsOnlyメソッドと違い順序も検証対象となります。

package jp.co.test;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;

public class MainTest {
  @Test
  public void test1() {
    String[] actual = {"name", "age"}; // 順序が同じ
    String[] expect = {"name", "age"}; // 順序が同じ
    assertThat(actual).containsExactly(expect);
  }
}

コメント

タイトルとURLをコピーしました