How to use JUnit and Hamcrest together?
Solution 1
junit provides new check assert methods named assertThat() which uses Matchers and should provide a more readable testcode and better failure messages.
To use this there are some core matchers included in junit. You can start with these for basic tests.
If you want to use more matchers you can write them by yourself or use the hamcrest lib.
The following example demonstrates how to use the empty matcher on an ArrayList:
package com.test;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class EmptyTest {
@Test
public void testIsEmpty() {
List myList = new ArrayList();
assertThat(myList, is(empty()));
}
}
(I included the hamcrest-all.jar in my buildpath)
Solution 2
If you're using a Hamcrest with a version greater or equal than 1.2, then you should use the junit-dep.jar
. This jar has no Hamcrest classes and therefore you avoid classloading problems.
Since JUnit 4.11 the junit.jar
itself has no Hamcrest classes. There is no need for junit-dep.jar
anymore.
Solution 3
Not exactly answering your question, but you should definitely try FEST-Assert fluent assertions API. It's competing with Hamcrest, but has a much easier API with only one static import required. Here is the code provided by cpater using FEST:
package com.test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import static org.fest.assertions.Assertions.assertThat;
public class EmptyTest {
@Test
public void testIsEmpty() {
List myList = new ArrayList();
assertThat(myList).isEmpty();
}
}
EDIT: Maven coordinates:
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
Solution 4
Also, if JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5 are being used, make sure mockito-all is not used. It contains Hamcrest core classes. Use mockito-core instead. The below config works :
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.1.1</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
Solution 5
Since versions are changing all the time, I'm posting to let people know that as of December 2, 2014, the instructions at http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in-a-maven-project-junit-mockito-hamcrest-assertj.html worked for me. I did not use AssertJ though, just these:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
yegor256
Lab director at Huawei, co-founder at Zerocracy, blogger at yegor256.com, author of Elegant Objects book; architect of Zold.
Updated on September 30, 2020Comments
-
yegor256 over 3 years
I can't understand how JUnit 4.8 should work with Hamcrest matchers. There are some matchers defined inside
junit-4.8.jar
inorg.hamcrest.CoreMatchers
. At the same time there are some other matchers inhamcrest-all-1.1.jar
inorg.hamcrest.Matchers
. So, where to go? Shall I explicitly include hamcrest JAR into the project and ignore matchers provided by JUnit?In particular, I'm interested in
empty()
matcher and can't find it in any of these jars. I need something else? :)And a philosophical question: why JUnit included
org.hamcrest
package into its own distribution instead of encouraging us to use original hamcrest library? -
yegor256 about 13 yearswhere exactly
org.hamcrest.Matchers.empty()
is located? Could you please give a link to the JAR file? -
cpater about 13 yearsYou can find all here: code.google.com/p/hamcrest and the download of hamcrest-all.jar here: code.google.com/p/hamcrest/downloads/…
-
yegor256 about 13 yearsLooks like hamcrest 1.2 is not in Maven Central repository. That's the problem I'm facing :(
-
cpater about 13 yearsOk in repo is only 1.1 and there is no empty Matcher. You can download the 1.2 jar and install it in your local repo: maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
-
Guillaume about 12 yearsI just swapped my assertion library. I was quite satisfied with hamcrest, but because of the junit problematic inclusion stuff and some hard to write test (with collection and generics), I'm know in love with FEST! Thanks for sharing.
-
Tom over 11 yearsHamcrest 1.3 has now been released, and is in maven central.
-
Adrien Be over 11 yearsA relevant comment from Stefan Birkner in the answers If you're using a Hamcrest with a version greater or equal than 1.2, then you should use the junit-dep.jar. This jar has no hamcrest classes and therefore you avoid classloading problems.
-
Grundlefleck about 11 yearsI thoroughly recommend using org.hamcrest.MatcherAssert.assertThat, rather than the JUnit version, as it will allow more descriptive error messages.
-
Jeff Evans over 9 yearsIt seems like as of JUnit 4.12, there is no longer a junit-dep.jar. Is that the case? And if so, are we meant to use the standalone Hamcrest 1.3 jar?
-
Stefan Birkner over 9 yearsAnswer to both questions: yes.
-
user64141 over 8 yearsFEST is no longer active. Use AssertJ, which is a fork of FEST. joel-costigliola.github.io/assertj
-
Dan Getz over 7 yearsI don't understand your second paragraph. I think you might have left out some words from what you meant to write?
-
Eugene Maysyuk over 5 yearsThere is no need to define both hamcrest-core and hamcrest-library dependencies at the same time since the hamcrest-library already defines hamcrest-core as a transitive dependency.