こんにちは。
キャスレーコンサルティングLS(リーディング・サービス)部の山口です。

「JUnitのアサーションライブラリAssertJ」をテーマに、
三回に分けてご紹介しております。

今回は第二回目、「AssertJを使うメリットとは何か」についての記事となります。
※第一回目は「JUnitのアサーションライブラリAssertJ ~環境構築編~」をご覧ください。
メジャーなアサーションライブラリ「Hamcrest」と比較し、
「AssertJ」の魅力的な点をご紹介していきます。

メソッドの書き方
まず、当然ですがメソッドの書き方は異なります。

例)nullチェック

//Hamcrest
String hello = "Hello World";
assertThat(hello,is(nullValue()));

//AssertJ
String hello = "Hello World";
assertThat(hello).isNull();

書き方については、「覚えるなり調べるなりすれば良い」という話で普通は終わりますが、
AssertJではチェック対象の値の型を見て、
使用可能なメソッド一覧が候補として、表示されます。(IDE補完機能)

つまり、上記の例では「assertThat(hello).」と入力すると、
チェック対象の変数「hello」の型(String)を、チェック出来るメソッドのみ
候補として表示してくれます。

「AssertJのメソッドの詳細に詳しくなくても書ける」というのは
大きなメリットかと思います。

複数のチェック処理をする場合
「ある変数のチェック処理を複数行いたい」という場合は、下記の書き方が可能です。

例)始まりと終わりが、特定の文字列になっているかをチェック

//Hamcrest
String hello = "Hello World";
assertThat(hello,is(startsWith("He")));
assertThat(hello,is(endsWith("ld")));

//AssertJ
String hello = "Hello World";
assertThat(hello).startsWith("He");
assertThat(hello).endsWith("ld");

上記の書き方であれば、どちらも特段差がありません。
しかし、AssertJでは下記の書き方も可能です。

//AssertJ
String hello = "Hello World";
assertThat(hello).startsWith("He").endsWith("ld");

つまり、メソッドを「.」で連続して書くことが可能である、ということです。
コード量の短縮にもなり、便利ですね。

※あまり違う意味を持つ処理を無理に連続して書くと、逆に見辛くなるかもしれません。
※ケースバイケースで、連続して書く/書かないの使い分けは、
した方が良いかもしれません。

コレクション系の比較
AssertJでは、コレクション系の比較がとても便利に出来ます。

【Listの場合】
例として、以下のようなUserクラスを作成

public class User {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

テストクラスにて、以下のようなListを作成

List list = new ArrayList();
List names = Lists.newArrayList("佐藤", "田中", "鈴木");
int count = 1;
for (String name : names) {
    User user = new User();
    user.setId(count);
    user.setName(name);
    list.add(user);
    count++;
}

上記List内のnameを、チェック

//Hamcrest
assertThat(list.get(0).getName(), is("佐藤"));
assertThat(list.get(1).getName(), is("田中"));
assertThat(list.get(2).getName(), is("鈴木"));

//AssertJ
assertThat(list).extracting("name").containsExactly("佐藤","田中","鈴木");

上記の通り、Hamcrestではnameの要素毎に値を
getし、チェックしていく必要がありますが、
AssertJでは「extracting」でnameの全要素を取得し、チェックが出来ます。
どれだけ便利かは、一目瞭然ですね。

【Mapの場合】
例として、以下のようなMapを作成

Map<String, Object> user = new HashMap<String,Object>();
user.put("name","佐藤");
user.put("age", 30);
user.put("gender","男");

Mapの値をチェック

//Hamcrest
assertThat(user, hasEntry("name", (Object) "佐藤"));
assertThat(user, hasEntry("age", (Object) 30));
assertThat(user, hasEntry("gender", (Object) "男"));

//AssertJ
assertThat(user).containsEntry("name", "佐藤").containsEntry("age", 30).containsEntry("gender", "男");

上記のように、Mapの中身をチェックする場合は
各要素毎にチェックしていく必要があるため、コードが冗長になりがちです。

しかし、「複数のチェック処理をする場合」にて記載した通り、
AssertJであればメソッドを連続して書いていけるため、
Map時のチェックが簡略化できます。

まとめ
今回は、Junitのアサーションライブラリ「AssertJ」の魅力を
お伝えする記事を書きました。

AssertJはHamcrestと比べ、
日本ではマイナーであまり日の当たらないものとなっていますが、
知ればとても便利なライブラリです。

本記事では伝えきれていない部分もあるかと思いますが、
少しでも多くの人が興味を持って頂ければ、それだけで嬉しいです。

また、HamcrestとAssertJは併用して利用可能です。
この処理はHamcrestを使い、こっちの処理はAssertJを使う、といった
使い分けが可能です。
効率の良い方法を取ることをお勧めします。

このAssertJに関する記事は次回で最後となりますが、
次回はAssertJ-DBを使ったデータベーステストの記事となります。
是非お読み頂き、AssertJのより深い魅力を知って頂ければ嬉しい限りです。

以上となります。
最後までご覧いただきありがとうございました。