やっぱりassertThatは良いよねという話
追記 2016/6/12
テスト結果のメッセージを読みやすくしたいだけなら、assertThatにreasonを書く方が楽ですね。
@Test public void test() { File file = new File("/tmp/hoge"); assertThat(file.getAbsoluteFile() + " should exist", file.exists(), is(equalTo(true))); }
java.lang.AssertionError: /tmp/hoge should exist Expected: is <true> but: was <false>
追記終わり
assertThatやっぱ便利ですねー、という話です。
assertEqualsは何のテストに失敗しているのか分かりにくかった
public class AssertEqualTests { @Test public void test() { final File test1 = new File("/tmp/test1.txt"); final File test2 = new File("/tmp/test2.txt"); final File test3 = new File("/tmp/test3.txt"); assertEquals(true, test1.exists()); assertEquals(true, test2.exists()); assertEquals(true, test3.exists()); } }
ファイルが存在しているかどうかをテストするだけです。
で、これを実行してみると、テストが失敗しました。
java.lang.AssertionError: expected:<true> but was:<false>
これだとどのファイルで失敗したか分からないですね。
まあスタックとレースをちゃんと見れば何行目のassertEqualsで失敗しているか分かるので判定はできるのですが、あまり直感的ではありません。
Matcherを作って原因を分かりやすくしよう!
そこでassertThatとhamcrestの出番です。
もっとわかりやすいメッセージを返してくれるMatcherを作ってみました。
public class FileExist extends TypeSafeMatcher<File> { private final boolean isEexpectedResult; private File inspected; public FileExist(boolean exceptedResult) { this.isEexpectedResult = exceptedResult; } @Override public void describeTo(Description description) { description.appendText(inspected.getAbsolutePath()); if (isEexpectedResult) { description.appendText(" exist"); } else { description.appendText(" does not exist"); } } @Override protected void describeMismatchSafely(File item, Description mismatchDescription) { mismatchDescription.appendText(inspected.getName()); if (isEexpectedResult) { mismatchDescription.appendText(" does not exist."); } else { mismatchDescription.appendText(" exist."); } } @Override protected boolean matchesSafely(File item) { this.inspected = item; return item.exists() == isEexpectedResult; } @Factory public static <T> Matcher<File> exist() { return new FileExist(true); } @Factory public static <T> Matcher<File> NotExist() { return new FileExist(false); } }
TypeSafeMatcher
ファイルを受け取って期待通り存在しているか、もしくは存在していないかをテストできます。
そしてdescribeToで成功時のメッセージを、describeMismatchSafelyで失敗時のメッセージを作成しています。
テストは以下のようになります。
public class AssertThatTests { @Test public void test() { final File test1 = new File("/tmp/test1.txt"); final File test2 = new File("/tmp/test2.txt"); final File test3 = new File("/tmp/test3.txt"); assertThat(test1,exist()); assertThat(test2,exist()); assertThat(test3,exist()); } }
そして実行結果。
java.lang.AssertionError: Expected: /tmp/test2.txt exist but: test2.txt does not exist.
test2.txtが存在していないというのが一目でわかりますねー。素敵です。
Matcherを簡単に作れるというのは、結果の分かりやすくする事にも役立つんですね。
ちょっとはまったこと。
Matcherを作るとき、どうしてもdescribeMismatchSafelyが見つからず@Overrideがエラーを吐いてしまいました。
原因は我らがstackoverflowで見つかりました。