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 FreeThe JUnit4.4 release notes talk about the various benefits of usingassertThat
over traditional assertXXX methods, which we will walk through one by one.
assertThat([value], [matcher statement]);
Readability
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:
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
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
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 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.
References
Published at DZone with permission of Mohammad Nadeem, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments