Thursday, April 19, 2012

Junit and Hamcrest - advisable to keep it separate

Junit now comes bundled with some parts of the Hamcrest library - with the Assert.assertThat method which takes in a hamcrest matcher as a parameter

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

along with a series of matchers in the org.junit.matchers.JUnitMatchers class.

Hamcrest core matchers along with the additional matcher libraries it provides are much more comprehensive than the one's that are packaged with JUnit, so at some point it would be natural to import a separate hamcrest library also into the project, and this is where the problems start.

For eg, if I wanted to use some matchers from the JUnitMatchers class and some from the native hamcrest one's, the imports would be along these lines:

import static org.junit.matchers.JUnitMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.CoreMatchers.*;

Unfortunately this will not work, a lot of static methods will start colliding at this point and the imports will have to be much more specific.

A very good work around is to keep junit separate from the hamcrest libraries, a way to do that is to not import core junit libraries but to import junit-dep version of the library where the hamcrest code has been stripped out, this way the hamcrest matchers and the assertThat method can be used without any conflicts with the junit libraries, the imports would look something like this:

import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.*;

and the dependencies in maven would be along these lines:
<dependency>
 <groupId>junit</groupId>
 <artifactId>junit-dep</artifactId>
 <version>4.8.1</version>
 <scope>test</scope>
</dependency>
<dependency>
 <groupId>org.hamcrest</groupId>
 <artifactId>hamcrest-core</artifactId>
 <version>1.2.1</version>
</dependency>
<dependency>
 <groupId>org.hamcrest</groupId>
 <artifactId>hamcrest-library</artifactId>
 <version>1.2.1</version>
</dependency>  

1 comment:

  1. This is no longer true starting with Version 4.11 of Junit

    ReplyDelete