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
とは異なります。予想される行と実際の行のペアごとに、このアルゴリズムが実行されるためです。
-
予想される行が実際の行と等しいかどうかを確認してください. もしそうなら
次のペアを続ける
。予想される行を正規表現として扱い、チェックを実行します
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で利用可能]です。