1.概要
この記事では、Javaテストで流暢で豊富なアサーションを作成するために使用されるオープンソースのコミュニティ主導のライブラリであるAssertJについて説明します。
この記事では、AssertJ-coreと呼ばれる基本的なAssertJモジュールで使用できるツールに焦点を当てています。
2.Mavenの依存関係
AssertJを使用するには、pom.xmlファイルに次のセクションを含める必要があります。
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.4.1</version>
<scope>test</scope>
</dependency>
この依存関係は、基本的なJavaアサーションのみを対象としています。 高度なアサーションを使用する場合は、モジュールを個別に追加する必要があります。
Java 7以前の場合は、AssertJコアバージョン2.xxを使用する必要があることに注意してください。
最新バージョンはここにあります。
3. 序章
AssertJは、次の目的で流暢で美しいアサーションを簡単に記述できるようにする一連のクラスとユーティリティメソッドを提供します。
- 標準Java
- Java 8
- グアバ
- ジョーダタイム
- Neo4Jと
- スイングコンポーネント
すべてのモジュールの詳細なリストは、プロジェクトのWebサイトで入手できます。
AssertJのドキュメントから、いくつかの例から始めましょう。
assertThat(frodo)
.isNotEqualTo(sauron)
.isIn(fellowshipOfTheRing);
assertThat(frodo.getName())
.startsWith("Fro")
.endsWith("do")
.isEqualToIgnoringCase("frodo");
assertThat(fellowshipOfTheRing)
.hasSize(9)
.contains(frodo, sam)
.doesNotContain(sauron);
上記の例は氷山の一角にすぎませんが、このライブラリを使用してアサーションを作成する方法の概要を説明します。
4. AssertJ in Action
このセクションでは、AssertJの設定とその可能性の調査に焦点を当てます。
4.1. 入門
ライブラリのjarがクラスパスにある場合、アサーションの有効化は、テストクラスに単一の静的インポートを追加するのと同じくらい簡単です。
import static org.assertj.core.api.Assertions.*;
4.2. アサーションを書く
アサーションを作成するには、常にオブジェクトを Assertions.assertThat()メソッドに渡すことから始めてから、実際のアサーションを実行する必要があります。
他のいくつかのライブラリとは異なり、以下のコードは実際にはまだ何もアサートせず、テストに決して失敗しないことを覚えておくことが重要です。
assertThat(anyRefenceOrValue);
IDEのコード補完機能を活用すると、非常にわかりやすいメソッドにより、AssertJアサーションの記述が非常に簡単になります。 IntelliJIDEA16では次のようになります。
ご覧のとおり、選択できるコンテキストメソッドは数十あり、それらはStringタイプでのみ使用できます。 このAPIのいくつかを詳細に調べて、いくつかの特定のアサーションを見てみましょう。
4.3。 物体アサーション
オブジェクトは、2つのオブジェクトが等しいかどうかを判断したり、オブジェクトのフィールドを調べたりするために、さまざまな方法で比較できます。
2つのオブジェクトの同等性を比較できる2つの方法を見てみましょう。 次の2つのDogオブジェクトfidoおよびfidosCloneがあるとします。
public class Dog {
private String name;
private Float weight;
// standard getters and setters
}
Dog fido = new Dog("Fido", 5.25);
Dog fidosClone = new Dog("Fido", 5.25);
同等性を次のアサーションと比較できます。
assertThat(fido).isEqualTo(fidosClone);
isEqualTo()がオブジェクト参照を比較するため、これは失敗します。 代わりにそれらのコンテンツを比較したい場合は、次のように isEqualToComparingFieldByFieldRecursively()を使用できます。
assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);
FidoとfidosCloneは、一方のオブジェクトの各フィールドがもう一方のオブジェクトのフィールドと比較されるため、フィールド比較による再帰フィールドを実行する場合は等しくなります。
オブジェクトを比較および縮小し、それらのフィールドを調べてアサートするためのさまざまな方法を提供する他の多くのアサーションメソッドがあります。 それらすべてを見つけるには、公式の AbstractObjectAssertドキュメントを参照してください。
4.4。 ブール値アサーション
真実のテストにはいくつかの簡単な方法があります。
- isTrue()
- isFalse()
それらの動作を見てみましょう。
assertThat("".isEmpty()).isTrue();
4.5。 Iterable / Array アサーション
IterableまたはArrayの場合、それらのコンテンツが存在することを表明する方法は複数あります。 最も一般的なアサーションの1つは、IterableまたはArrayに特定の要素が含まれているかどうかを確認することです。
List<String> list = Arrays.asList("1", "2", "3");
assertThat(list).contains("1");
または、リストが空でない場合:
assertThat(list).isNotEmpty();
または、リストが特定の文字で始まる場合。 例:「1」:
assertThat(list).startsWith("1");
同じオブジェクトに対して複数のアサーションを作成する場合は、それらを簡単に結合できることに注意してください。
これは、提供されたリストが空ではなく、「1」要素を含み、nullを含まず、要素「2」、「3」のシーケンスを含むかどうかをチェックするアサーションの例です。
assertThat(list)
.isNotEmpty()
.contains("1")
.doesNotContainNull()
.containsSequence("2", "3");
もちろん、これらのタイプにはさらに多くの可能なアサーションが存在します。 それらすべてを見つけるには、公式の AbstractIterableAssertドキュメントを参照してください。
4.6。 キャラクターアサーション
文字タイプのアサーションには、ほとんどの場合、比較が含まれ、特定の文字がUnicodeテーブルからのものであるかどうかのチェックも含まれます。
これは、指定された文字が「a」ではなく、Unicodeテーブルにあり、「b」より大きく、小文字であるかどうかをチェックするアサーションの例です。
assertThat(someCharacter)
.isNotEqualTo('a')
.inUnicode()
.isGreaterThanOrEqualTo('b')
.isLowerCase();
すべての文字タイプのアサーションの詳細なリストについては、 AbstractCharacterAssertドキュメントを参照してください。
4.7。 クラスアサーション
Class タイプのアサーションは、主にそのフィールド、 Class タイプ、アノテーションの存在、およびクラスのファイナリティのチェックに関するものです。
クラスRunnableがインターフェースであることを表明したい場合は、次のように記述する必要があります。
assertThat(Runnable.class).isInterface();
または、一方のクラスがもう一方のクラスから割り当て可能かどうかを確認する場合:
assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);
可能なすべてのClassアサーションは、 AbstractClassAssertドキュメントで表示できます。
4.8。 ファイルアサーション
File アサーションは、特定の File インスタンスが存在するか、ディレクトリまたはファイルであるか、特定のコンテンツがあるか、読み取り可能か、または拡張子が指定されているかどうかを確認することです。
ここでは、特定のファイルが存在するかどうかをチェックするアサーションの例を見ることができます。これは、ディレクトリではなくファイルであり、読み取りと書き込みが可能です。
assertThat(someFile)
.exists()
.isFile()
.canRead()
.canWrite();
可能なすべてのクラスアサーションは、 AbstractFileAssertドキュメントで表示できます。
4.9。 ダブル/フロート/整数アサーション
Double / Float /Integerおよびその他のNumberタイプ
数値アサーションとは、特定のオフセット内またはオフセットなしで数値を比較することです。 たとえば、特定の精度に従って2つの値が等しいかどうかを確認する場合は、次のように実行できます。
assertThat(5.1).isEqualTo(5, withPrecision(1d));
オフセットオブジェクトを生成するために、すでにインポートされている withPrecision(Double offset)ヘルパーメソッドを使用していることに注意してください。
その他のアサーションについては、AbstractDoubleAssertドキュメントにアクセスしてください。
4.10。 InputStream アサーション
使用可能なInputStream固有のアサーションは1つだけです。
- hasSameContentAs(InputStreamが期待されます)
そして実際に:
assertThat(given).hasSameContentAs(expected);
4.11。 地図アサーション
Map アサーションを使用すると、マップに特定のエントリ、エントリのセット、またはキー/値が個別に含まれているかどうかを確認できます。
ここでは、特定のマップが空ではなく、数字キー「2」を含み、数字キー「10」を含まず、エントリを含むアサーションの例を見ることができます: key:2、value:“ a 」:
assertThat(map)
.isNotEmpty()
.containsKey(2)
.doesNotContainKeys(10)
.contains(entry(2, "a"));
その他のアサーションについては、 AbstractMapAssertドキュメントを参照してください。
4.12。 スロー可能アサーション
Throwable アサーションでは、たとえば、例外のメッセージ、スタックトレースを検査し、例外がすでにスローされているかどうかをチェックまたは検証できます。
特定の例外がスローされたかどうかをチェックし、「c」で終わるメッセージがあるアサーションの例を見てみましょう。
assertThat(ex).hasNoCause().hasMessageEndingWith("c");
その他のアサーションについては、AbstractThrowableAssertドキュメントを参照してください。
5. アサーションの説明
さらに高い詳細レベルを実現するために、アサーションに対して動的に生成されたカスタム記述を作成できます。 これを行うための鍵は、 as(String description、Object…args)メソッドです。
アサーションを次のように定義する場合:
assertThat(person.getAge())
.as("%s's age should be equal to 100", person.getName())
.isEqualTo(100);
これは、テストを実行するときに得られるものです。
[Alex's age should be equal to 100] expected:<100> but was:<34>
6. Java 8
AssertJは、Java8の関数型プログラミング機能を最大限に活用します。 例を詳しく見て、実際の動作を見てみましょう。 まず、Java7でそれをどのように行うかを見てみましょう。
assertThat(fellowshipOfTheRing)
.filteredOn("race", HOBBIT)
.containsOnly(sam, frodo, pippin, merry);
ここでは、レースHobbitでコレクションをフィルタリングしており、Java8では次のようなことができます。
assertThat(fellowshipOfTheRing)
.filteredOn(character -> character.getRace().equals(HOBBIT))
.containsOnly(sam, frodo, pippin, merry);
このシリーズの今後の記事で、AssertJのJava8機能について説明します。 上記の例は、AssertJのWebサイトから抜粋したものです。
7. 結論
この記事では、AssertJが提供する可能性と、コアJavaタイプの最も一般的なアサーションについて簡単に説明しました。
すべての例とコードスニペットの実装は、GitHubプロジェクトにあります。