Hamcrest and junit4.4

Posted by Andy Gavin on Tue, 2008-03-11 20:55

Since the Hamcrest matching library has been taken out of jmock and placed in its own package it looks to be generally useful for the application developer.  Hamcrest support has now gone into the new version of junit4.4, along with some other interesting features. 

The assertThat assertion now takes a matcher which provides a better alternative to assertTrue improving the error report when a test does fail.  Here are some examples:

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
 
public class Junit4FeaturesTest {
 @org.junit.Test
 public void testArrays()
 {
    assertThat(new Integer[] {1,2,3,4,5},equalTo(new Integer[]{1,2,3,4,5}));
    assertThat(new Integer[] {1,2,3,4,5},not(new Integer[] {1,2}));
 }
}

If either of these tests were to fail the framework will now display the contents of the two arrays for inspection, avoiding the need for hand-crafted loops or helper functions. These are hamcrest matchers from the org.hamcrest.CoreMatchers, junit however provides some of its own matchers:

import static org.junit.Assert.*;
import static org.junit.matchers.JUnitMatchers.*;
 
import org.junit.Test;
 
public class Junit4FeaturesTest {
  @Test
  public void testSubstring()
  {
	assertThat("Hello World",containsString("Hello"));
  }
  @Test
  public void testCollections()
  {
	assertThat(java.util.Arrays.asList(1,2),hasItem(1));
	assertThat(java.util.Arrays.asList(1,2),hasItems(1,2));
  }
}

It also seems that a subset of the matchers available with the hamcrest library are shipped with Junit4.4. So it is worth getting hold of other matchers, perhaps by downloading the hamcrest library or jMock to improve the range available. Some basic operations are surprisingly missing from the hamcrest bundled in JUnit. These include the numeric comparisons. These would seem like they should belong in the core and are very useful for assertion.

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*; // provided by additional jar
 
import org.junit.Test;
 
public class Junit4FeaturesTest {
  @Test
  public void testNumericComparison()
  {
	assertThat(1,lessThan(2));
	assertThat(2,greaterThan(1));
	assertThat(2,greaterThanOrEqualTo(2));
	assertThat(1,lessThanOrEqualTo(1));
  }
 
}

The use of this library may be quite a blow to other mocking frameworks. Using the hamcrest library means that JMock probably should be your mocking framework of choice: any custom Matchers you write will work with assert as well as jMock's expectations. Update: I was particularly thinking of Easymock here which was the other widely used mocking framework: which I think might loose ground.

BlogTag: 

Comments

The use of this library may be quite a blow to other mocking frameworks. Using the hamcrest library means that JMock probably should be your mocking framework of choice: any custom Matchers you write will work with assert as well as jMock's expectations.

Except of course that JMock isn't the only mocking framework which supports Hamcrest matchers. The lovely Mockito being an example.

Add new comment