Junit4.4 Release notes talks various benefits of using assertThat over the traditional assertXXX methods, will just walk through one by one.
assertThat([value], [matcher statement]); |
Readability
The new syntax allows you to think in terms of subject, verb, object (asset that actual is expected) rather than (as in traditional assert statements) verb, object and subject (assert equals expected actual)
Suppose that, a variable (actual) should be 100 after a test, here is how one would do in both versions
assertEquals(100, actual);
// assertEquals(expected, actual); In general
It is easy to forget the correct order and type it in the reverse order
assertThat(actual, equalTo(100));
//OR
assertThat(actual, is(equalTo(100)));
//OR
assertThat(actual, is(100));
With this version there is no confusion, every thing is crystal clear.
It also reads more like a sentence: “Assert that the actual value is equal to the expected value 100.”
Here is how, check of not equals done in both versions
assertFalse(expected.equals(actual));
Since there is no “assertNotEquals” (unless it’s custom coded) we have to use assertFalse and do an equals on the two variables.
assertThat(actual, is(not(equalTo(expected))));
//OR
assertThat(actual, is(not(expected)));
Better/Detailed Failure Messages
assertTrue("Number not between 1 and 3!", 1 < 5 && 5 < 3);
//java.lang.AssertionError: Number not between 1 and 3!
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertThat;
assertThat(5 , allOf(greaterThan(1), lessThan(3)));
//java.lang.AssertionError:
Expected: (a value greater than <1> and a value less than <3>)
but: a value less than <3> <5> was greater than <3>
Type Safety
assertEquals("abc", 123);
//Compiles but fails
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
assertThat(123, equalTo("abc"));
//Does not even compiles
Note JUnit has dependency with only hamcrest-core, to take full benefit of matchers you can use hamcrest-all, and even go beyond and use AssertJ (Fluent Assertion API)
AssertJ
Here are some of the examples with AssertJ
// basic assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);
// chaining string specific assertions
assertThat(frodo.getName()).startsWith("Fro")
.endsWith("do")
.isEqualToIgnoringCase("frodo");
// collection specific assertions (there are plenty more)
// in the examples below fellowshipOfTheRing is a List<TolkienCharacter>
assertThat(fellowshipOfTheRing).hasSize(9)
.contains(frodo, sam)
.doesNotContain(sauron);
// as() is used to describe the test and will be shown before the error message
assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);
Note : If the library owner says, prefer this over that, I would switch sooner than later, switch does not mean do all at once, it means, do it, the new way for new test cases first