JUnit 4とJUnit 5のアサーション

1前書き

この記事では、JUnitで利用可能なアサーションについて詳しく探ります。

リンク:/junit-5-migration[JUnit 4からJUnit 5への移行]とリンク:/junit-5[JUnit 5へのガイド]の記事では、JUnit 4で利用可能なさまざまなアサーションについて詳しく説明します。そしてJUnit 5。

また、JUnit 5でのアサーションに対する機能強化についても説明します。

2アサーション

  • アサーションはテストでアサーション条件をサポートするためのユーティリティメソッドです。これらのメソッドは、JUnit 4の Assert クラス、およびJUnit 5の Assertions クラスを通じてアクセスできます。

テストとアサーション自体の読みやすさを向上させるために、常にそれぞれのクラスを静的にインポートすることをお勧めします。このようにして、表現クラスを接頭辞として使わずにアサーションメソッド自体を直接参照することができます。

JUnit 4で利用可能なアサーションの調査を始めましょう。

3 JUnit 4 でのアサーション

このバージョンのライブラリでは、すべてのプリミティブ型 Objects、 、および arrays (プリミティブまたは__Objectsのいずれか)に対してアサーションを使用できます。

アサーション内のパラメータの順序は、期待値とそれに続く実際の値です。オプションで、最初のパラメータは、評価された条件のメッセージ出力を表す String メッセージです。

assertThat アサーションの定義方法がわずかに異なる点が1つだけありますが、後で説明します。

assertEquals から始めましょう。

3.1. assertEquals

assertEquals アサーションは、期待値と実際の値が等しいことを確認します。

@Test
public void whenAssertingEquality__thenEqual() {
    String expected = "Baeldung";
    String actual = "Baeldung";

    assertEquals(expected, actual);
}

アサーションが失敗したときに表示するメッセージを指定することもできます。

assertEquals("failure - strings are not equal", expected, actual);

3.2. assertArrayEquals

2つの配列が等しいと主張したい場合は、__assertArrayEqualsを使用できます。

@Test
public void whenAssertingArraysEquality__thenEqual() {
    char[]expected = {'J','u','n','i','t'};
    char[]actual = "Junit".toCharArray();

    assertArrayEquals(expected, actual);
}

両方の配列が null の場合、アサーションはそれらが等しいと見なします。

@Test
public void givenNullArrays__whenAssertingArraysEquality__thenEqual() {
    int[]expected = null;
    int[]actual = null;

    assertArrayEquals(expected, actual);
}

3.3. assertNotNull および assertNull

オブジェクトが null かどうかをテストしたい場合は、 assertNull アサーションを使用できます。

@Test
public void whenAssertingNull__thenTrue() {
    Object car = null;

    assertNull("The car should be null", car);
}

反対に、オブジェクトがnullであってはならないとアサートしたい場合は、__assertNotNullアサーションを使用できます。

3.4. assertNotSame および assertSame

assertNotSame を使用すると、2つの変数が同じオブジェクトを参照していないかどうかを確認できます。

@Test
public void whenAssertingNotSameObject__thenDifferent() {
    Object cat = new Object();
    Object dog = new Object();

    assertNotSame(cat, dog);
}

それ以外の場合、2つの変数が同じオブジェクトを参照していることを確認したい場合は、 assertSame アサーションを使用できます。

3.5. assertTrue および assertFalse

特定の条件が true または false であることを確認したい場合は、それぞれ assertTrue assertionまたは assertFalse oneを使用できます。

@Test
public void whenAssertingConditions__thenVerified() {
    assertTrue("5 is greater then 4", 5 > 4);
    assertFalse("5 is not greater then 6", 5 > 6);
}

3.6. 失敗

fail アサーションは、 AssertionFailedError をスローするテストに失敗します。実際の例外がスローされたことを検証するため、または開発中にテストを失敗させたいときに使用できます。

最初のシナリオでどのように使用できるのかを見てみましょう。

@Test
public void whenCheckingExceptionMessage__thenEqual() {
    try {
        methodThatShouldThrowException();
        fail("Exception not thrown");
    } catch (UnsupportedOperationException e) {
        assertEquals("Operation Not Supported", e.getMessage());
    }
}

3.7. assertThat

assertThat アサーションは、他のアサーションと比べてパラメーターの順序が逆になっているJUnit 4の唯一のものです。

この場合、アサーションにはオプションの失敗メッセージ、実際の値、および Matcher オブジェクトがあります。

このアサーションを使用して配列に特定の値が含まれているかどうかを確認する方法を見てみましょう。

@Test
public void testAssertThatHasItems() {
    assertThat(
      Arrays.asList("Java", "Kotlin", "Scala"),
      hasItems("Java", "Kotlin"));
}

Matcher オブジェクトで assertThat アサーションを強力に使用することに関する追加情報は、リンク:/java-junit-hamcrest-guide[Hamcrestによるテスト]で入手できます。

4 JUnit 5のアサーション

JUnit 5はJUnit 4の多くのアサーションメソッドを維持しながら、Java 8サポートを利用する新しいメソッドをいくつか追加しました。

このバージョンのライブラリでも、すべてのプリミティブ型 Objects、 、および配列(プリミティブまたはオブジェクトのいずれか)に対してアサーションを使用できます。

アサーションのパラメータの順序が変わり、最後のパラメータとして出力メッセージパラメータが移動しました。 Java 8のサポートのおかげで、出力メッセージは Supplier になり、遅延評価が可能になります。

JUnit 4でも利用可能なアサーションの検討を始めましょう。

4.1. assertArrayEquals

assertArrayEquals アサーションは、期待される配列と実際の配列が等しいことを検証します。

@Test
public void whenAssertingArraysEquality__thenEqual() {
    char[]expected = { 'J', 'u', 'p', 'i', 't', 'e', 'r' };
    char[]actual = "Jupiter".toCharArray();

    assertArrayEquals(expected, actual, "Arrays should be equal");
}

配列が等しくない場合は、「__配列は等しい必要があります」というメッセージが出力として表示されます。

4.2. assertEquals

2つの floats が等しいと主張したい場合は、単純な assertEquals アサーションを使用できます。

@Test
public void whenAssertingEquality__thenEqual() {
    float square = 2 **  2;
    float rectangle = 2 **  2;

    assertEquals(square, rectangle);
}

ただし、実際の値が事前定義されたデルタだけ期待値と異なることを主張したい場合は、 assertEquals を使用できますが、デルタ値を3番目のパラメータとして渡す必要があります。

@Test
public void whenAssertingEqualityWithDelta__thenEqual() {
    float square = 2 **  2;
    float rectangle = 3 **  2;
    float delta = 2;

    assertEquals(square, rectangle, delta);
}

4.3. assertTrue および assertFalse

assertTrue アサーションを使用すると、提供された条件が true であることを確認できます。

@Test
public void whenAssertingConditions__thenVerified() {
    assertTrue(5 > 4, "5 is greater the 4");
    assertTrue(null == null, "null is equal to null");
}

ラムダ式のサポートにより、 boolean 条件の代わりに BooleanSupplier をアサーションに提供することが可能です。

assertFalse アサーションを使用して BooleanSupplier の正当性をどのように主張できるかを見てみましょう。

@Test
public void givenBooleanSupplier__whenAssertingCondition__thenVerified() {
    BooleanSupplier condition = () -> 5 > 6;

    assertFalse(condition, "5 is not greater then 6");
}

4.4. assertNull および assertNotNull

オブジェクトが null ではないとアサートしたい場合は、 assertNotNull アサーションを使用できます。

@Test
public void whenAssertingNotNull__thenTrue() {
    Object dog = new Object();

    assertNotNull(dog, () -> "The dog should not be null");
}

反対に、 assertNull アサーションを使用して、実際の値が null かどうかを確認できます。

@Test
public void whenAssertingNull__thenTrue() {
    Object cat = null;

    assertNull(cat, () -> "The cat should be null");
}

どちらの場合も、失敗メッセージは Supplier なので怠惰な方法で取得されます。

4.5. assertSame assertNotSame

期待されたものと実際のものが同じ Object を参照していると主張したい場合は、 assertSame アサーションを使用する必要があります。

@Test
public void whenAssertingSameObject__thenSuccessfull() {
    String language = "Java";
    Optional<String> optional = Optional.of(language);

    assertSame(language, optional.get());
}

反対に、 assertNotSame を使用できます。

4.6. 失敗します

fail アサーションは、根本的な原因と同様に提供された失敗メッセージでテストに失敗します。開発が完了していないときにテストをマークするのに役立ちます。

@Test
public void whenFailingATest__thenFailed() {
   //Test not completed
    fail("FAIL - test not completed");
}

4.7. assertAll

JUnit 5で導入された新しいアサーションの1つは assertAll です。

このアサーションにより、すべてのアサーションが実行され、それらの失敗がまとめて報告される、グループ化されたアサーションを作成できます。詳細には、このアサーションは、 MultipleFailureError のメッセージ文字列に含まれる見出し、および Executableの Stream__を受け入れます。

グループ化されたアサーションを定義しましょう。

@Test
public void givenMultipleAssertion__whenAssertingAll__thenOK() {
    assertAll(
      "heading",
      () -> assertEquals(4, 2 **  2, "4 is 2 times 2"),
      () -> assertEquals("java", "JAVA".toLowerCase()),
      () -> assertEquals(null, null, "null is equal to null")
    );
}

グループ化されたアサーションの実行は、実行可能ファイルの1つがブラックリストに登録された例外(たとえば、 OutOfMemoryError )をスローした場合にのみ中断されます。

4.8. assertIterableEquals

assertIterableEquals は、期待されるイテラブルと実際のイテラブルが深く等しいことを表明します。

等しくなるためには、両方のiterableが同じ要素を同じ順序で返さなければならず、2つのiterableが同じである必要はない。

このことを考慮して、異なるタイプの2つのリスト( LinkedList ArrayList など)が等しいことをどのように主張できるかを見てみましょう。

@Test
public void givenTwoLists__whenAssertingIterables__thenEquals() {
    Iterable<String> al = new ArrayList<>(asList("Java", "Junit", "Test"));
    Iterable<String> ll = new LinkedList<>(asList("Java", "Junit", "Test"));

    assertIterableEquals(al, ll);
}

assertArrayEquals と同様に、両方のイテラブルがnullの場合、それらは等しいとみなされます。

4.9. assertLinesMatch

assertLinesMatch は、予想される String のリストが実際のリストと一致することを表明します。

このメソッドは assertEquals および assertIterableEquals とは異なります。予想される行と実際の行のペアごとに、このアルゴリズムが実行されるためです。

  1. 予想される行が実際の行と等しいかどうかを確認してください. もしそうなら

次のペアを続ける 。予想される行を正規表現として扱い、チェックを実行します

String . matches() メソッドを使います。もしそうならそれは次のものに続く ペア 。予想される行が早送りマーカーであるかどうかを確認してください。はいの場合

早送りし、手順1からアルゴリズムを繰り返します

このアサーションを使用して、2つの String のリストに一致する行があることをアサートする方法を見てみましょう。

@Test
public void whenAssertingEqualityListOfStrings__thenEqual() {
    List<String> expected = asList("Java", "\\d+", "JUnit");
    List<String> actual = asList("Java", "11", "JUnit");

    assertLinesMatch(expected, actual);
}

4.10. assertNotEquals

assertNotEquals アサーションは、 assertEquals を補完するものとして、期待値と実際の値が等しくないことを表明しています。

@Test
public void whenAssertingEquality__thenNotEqual() {
    Integer value = 5;//result of an algorithm

    assertNotEquals(0, value, "The result cannot be 0");
}

両方とも null の場合、アサーションは失敗します。

4.11. assertThrows

単純さと読みやすさを増すために、新しい assertThrows アサーションにより、実行可能ファイルが指定された例外タイプをスローしたかどうかを明確かつ簡単にアサートすることができます。

スローされた例外をアサートする方法を見てみましょう。

@Test
void whenAssertingException__thenThrown() {
    Throwable exception = assertThrows(
      IllegalArgumentException.class,
      () -> {
          throw new IllegalArgumentException("Exception message");
      }
    );
    assertEquals("Exception message", exception.getMessage());
}

例外がスローされない場合、または異なるタイプの例外がスローされる場合は、アサーションは失敗します。

4.12. assertTimeout および assertTimeoutPreemptively

与えられた Executable の実行が与えられた Timeout の前に終了するとアサートしたい場合は、 assertTimeout アサーションを使用できます。

@Test
public void whenAssertingTimeout__thenNotExceeded() {
    assertTimeout(
      ofSeconds(2),
      () -> {
       //code that requires less then 2 minutes to execute
        Thread.sleep(1000);
      }
    );
}

ただし、 assertTimeout アサーションを使用すると、指定された実行可能ファイルは呼び出しコードの同じスレッド内で実行されます。その結果、タイムアウトを超えてもサプライヤの実行が優先的に中止されることはありません。

実行可能ファイルの実行がタイムアウトを超えると実行が中止されることを確認したい場合は、 assertTimeoutPreemptively アサーションを使用できます。

どちらのアサーションも、 Executableの代わりに a ThrowingSupplier を受け入れることができます。これは、オブジェクトを返し、__Throwableをスローする可能性がある一般的なコードブロックを表します。

5結論

このチュートリアルでは、JUnit 4とJUnit 5の両方で利用可能なすべてのアサーションについて説明しました。

新しいアサーションの紹介とラムダのサポートにより、JUnit 5で行われた改善点について簡単に説明しました。

いつものように、この記事の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/junit-5[GitHubで利用可能]です。