Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

JUnit testing is mostly implemented with assertEquals or asseerTrue .It is the default assertion that’s used in practice.

However writing tests in that style doesn't capture the essence of the test because it forces us to fit the class under test functionality with the capabilities of the framework.


For example if we want to test that a List is empty we will write the following code


assertTrue(myList.isEmpty())








instead of something like


assertEmpty(myList)









Wouldn't you like to have a tool that allows you to pick out precisely the aspect under test and describe the values it should have? to a controlled level of precision? one that will help greatly in writing tests that are "just right"?

Hamcrest is precisely that! It is a tool that will fail tests when the behavior of the aspect under test deviates from the expected behavior, yet continue to pass when minor, unrelated changes to the behavior are made.


Using Hamcrest the example above can be written like:


assertThat(myList, is(empty()))






A good starting place is the assertThat() method that can now almost always be used in place of the traditional assertEquals(). assertThat() can be found in org.junit.Assert, but it defines using Hamcrest matchers in the signature:

static <T> void assertThat(T actual, org.hamcrest.Matcher<T> matcher)

The subject of the assertion is the first method parameter. The second method parameter is a matcher.
Admittedly the new assertThat() style is a bit more verbose, but it readability is significantly enhanced. Code gets read a lot more often that it’s written so readability of tests is important as well.



These are the core methods contained in org.hamcrest.CoreMatchers class they all just get used by means of a static import of org.hamcrest.CoreMatchers. They cover the following static methods in alphabetical order

  • allOf()
  • any()
  • anyOf()
  • anything()
  • describedAs()
  • equalTo()
  • instanceOf()
  • is()
  • not()
  • notNullValue()
  • nullValue()
  • sameInstance()

I'll elaborate on some of those matchers, full explanation can be found at: Matchers (Hamcrest)

allOf()

allOf() is a simple assertion that just says all of the matcher arguments must be true. So in this example the string “Hello” must be not be null, an instance of String, and equal to the value “Hello”.


@Test
public void allOfExampleShowsAllMatchersMustAllBeTrue() throws Exception {
  assertThat("Hello", is(allOf(notNullValue(), instanceOf(String.class), equalTo("Hello"))));
}


A negative example might look like this:


@Test
public void allOfExampleShowsFailingIfOneMatcherDoesNotMatch() throws Exception {
  assertThat("Hello", is(not(allOf(notNullValue(), instanceOf(Integer.class)))));
}


equalTo()

This is one of the core matchers that duplicates the functionality of the old assertEquals().


@Test
public void equalToExampleAddingTwoPlusTwo() throws Exception {
  assertThat(2 + 2, is(equalTo(4)));
}

is()

It is probably my favorite matcher, primarily used for syntactic sugar to increase the readability. The following silly example shows its use as syntactic sugar by using it three times in a row:


@Test
public void isExampleShortCutAsJustSyntacticSugarUsedThreeTimes() throws Exception {
  assertThat("Hello", is(is(is(notNullValue()))));
}


It can also be used as a shortcut for instanceOf when you pass in a class argument:


@Test
public void isExampleShortCutForIsInstanceOfClass() throws Exception {
  assertThat("Hello", is(String.class));
  assertThat("Hello", instanceOf(String.class));
}


And there is a shortcut for equalsTo as well where you pass in any value:


@Test
public void isExampleShortCutForIsEqualTo() throws Exception {
  assertThat("Hello", is("Hello"));
  assertThat("Hello", equalTo("Hello"));
}