The Benefit Of Using assertThat Over Other Assert methods

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 subjectverbobject (asset that actual is expected) rather than (as in traditional assert statements) verbobject 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

References 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s