The Benefit of Using AssertThat Over Other Assert Methods
The latest JUnit4.4 release notes indicate that it's better to use AssertThat over other Assert methods.
Join the DZone community and get the full member experience.Join For Free
The JUnit4.4 release notes talk about the various benefits of using
assertThat over traditional assertXXX methods, which we will walk through one by one.
assertThat([value], [matcher statement]);
The new syntax allows you to think in terms of subject, verb, and object (asset that actual is expected) rather than (as in traditional assert statements) verb, object, and subject (assert equals expected actual)
Now, suppose that a variable (actual) should be 100 after a test; here is how one would do that 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; everything 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 is done in both versions:
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>
assertEquals("abc", 123); //Compiles but fails
Note that JUnit has a 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):
import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; assertThat(123, equalTo("abc")); //Does not even compiles
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 that if the library owner says they prefer this over that, I would switch sooner rather than later; switch does not mean you do it all at once; it just means that, first, you do it the new way for new test cases.
Published at DZone with permission of Mohammad Nadeem, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.