JUnit4 で List の assertThat を簡潔に書きたい
Java でプログラムを書くときは、プライベート・仕事を問わず JUnit を使ってユニットテストを書くようにしていますが、List
の assert
文をベタに書く癖がついてしまって、何とかしたいなぁと思ったので調べたことをメモしておきます。
目次
1. 動作環境
動作環境は次の通りです。
まずは Java のバージョン。
$ java -version java version "1.7.0_11" Java(TM) SE Runtime Environment (build 1.7.0_11-b21) Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)
JUnit は 2013/08/26 時点での最新である 4.11 を使いました。
JAR のダウンロードですが、Maven であれば次の dependency を pom.xml に貼り付けます。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
その後、次のコマンドを実行すればローカルリポジトリに JAR がダウンロードされます。
$ mvn eclipse:eclipse -DdownloadSources=true
また Maven を使わずに JAR を直接ダウンロードしてプロジェクトに組み込む場合は次のサイトからダウンロードできます。
ダウンロードページの URL は次になります。
2. List の assert 文をベタに書くとこんな感じ
ベタに List
の assert
文を書くとこんな感じになります。
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "6"); // Verify // まずは List のサイズが期待値通りであるかを確認する assertThat(list.size(), is(6)); // で、その後に、個々の要素について期待値通りであるかを確認していく assertThat(list.get(0), is("1")); assertThat(list.get(1), is("2")); assertThat(list.get(2), is("3")); assertThat(list.get(3), is("4")); assertThat(list.get(4), is("5")); assertThat(list.get(5), is("6"));
「なんだかなぁ~」という感じのテストコードですが、「テストを書かないよりずっとマシだろ」とか「カッコ悪いけど、どこでコケたのか一目瞭然だ!」とか開き直り、こんな感じのテストコードをずっと書いてきました。
が、個々の要素を確認するために assertThat
をズラズラっと書く行為が、やっと面倒くさいと感じるようになってきました。
3. もうちょっと簡潔に書けないものかと調べてみた
で、調べてみました。
3-1. 要素が List に含まれているかを確認する
org.hamcrest.Matchers#hasItem(T item)
Matchers#hasItem
を使うと、引数に指定した要素が含まれているかを確認できます。
このメソッドだと1つの要素についてしか確認できませんが、次のメソッドを使うと複数の要素について確認できます。
org.hamcrest.Matchers#hasItems(T... items)
Matchers#hasItems
の引数に指定する要素の順番は検証結果に関係がありません。
どういうことかというと、次の assertThat
はどちらもパスします。
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "6"); // Verify assertThat(list, hasItems("1", "2", "3", "4", "5", "6")); assertThat(list, hasItems("6", "5", "4", "3", "2", "1"));
Matchers#hasItems
は、引数の要素の順番通りに実効値が格納されているのかを確認する仕様ではないということです。
引数の要素があるのかないのかを確認するだけなので上の2例はどちらもパスするのです。
3-2. 要素が List に指定の順番で格納されているかを確認する
org.hamcrest.Matchers#contains(E... items)
Matchers#hasItems
は「含まれているか」だけを確認する用途に使いますが、「順番通りに含まれているか」を確認するケースのほうが多いと思います。
そんなときは Matchers#contains
を使います。
「順番通りに」なので2番めの assertThat
は失敗します。
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "6"); // Verify assertThat(list, contains("1", "2", "3", "4", "5", "6")); // こちらはグリーン assertThat(list, contains("6", "5", "4", "3", "2", "1")); // こちらはレッド
一気にぐわっと確認してくれるので、最初に書いたベタな assert
文よりもずっと読みやすく、かつ、簡潔なコードになりました。
あくまで自分比ですが。。。
Googleアドセンス用(PC)
関連記事
-
-
JUnit4 で JavaBeans の assertThat を簡潔に書きたい
今回も JUnit ネタです。 前回は List の assertThat を簡潔に書く方法につい
-
-
JUnit4 の Enclosed を使ったテストクラスサンプル
JUnit 本である「JUnit実践入門」を読んでいます。 体系的にまとめられている良書で、勉強にな
-
-
JUnit4 のパラメータ化テストは4通りの方法で書ける
JUnit 本である「JUnit実践入門」でテストの書き方を勉強しています。 本書でも紹介されている