If you want to learn how you can work smarter and save time when you are writing tests with JUnit 5, you should take a look at my Introduction to JUnit 5 course. It has 24 lessons, 47 exercises, and 13 quizzes.
This blog post describes how we can write assertions with Hamcrest when we are writing tests with JUnit 5. After we have finished this blog post, we:
- Can get the required dependencies with Maven and Gradle.
- Know how we can write basic assertions with Hamcrest.
- Understand how we can combine multiple Hamcrest matchers.
- Can customize the error message shown when an assertion fails.
Let's begin.
Getting the Required Dependencies
Before we can write assertions with Hamcrest, we have to ensure that the hamcrest-library
dependency (version 2.2) is found from the classpath.
If we are using Maven, we have to add the hamcrest-library
dependency to the test
scope. We can do this by adding the following snippet to the dependencies
section of our pom.xml file:
<dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> <version>2.2</version> <scope>test</scope> </dependency>
If we are using Gradle, we have to add the hamcrest-library
dependency to the testImplementation
dependency configuration. We can do this by adding the following snippet to our build.gradle file:
dependencies { testImplementation( 'org.hamcrest:hamcrest-library:2.2' ) }
After we have ensured that the hamcrest-library
dependency is found from the classpath, we can write assertions with Hamcrest. Let's find out how we can do it.
Writing Assertions With Hamcrest
If you have used Hamcrest with JUnit 4, you will probably remember that you had to use the assertThat()
method of the org.junit.Assert
class. However, the JUnit 5 API doesn't have a method that takes a Hamcrest matcher as a method parameter. The JUnit 5 User Guide explains this design decision as follows:
However, JUnit Jupiter's
org.junit.jupiter.api.Assertions
class does not provide anassertThat()
method like the one found in JUnit 4'sorg.junit.Assert
class which accepts a HamcrestMatcher
. Instead, developers are encouraged to use the built-in support for matchers provided by third-party assertion libraries.
In other words, if we want to use Hamcrest matchers, we have to use the assertThat()
method of the org.hamcrest.MatcherAssert
class. This method takes either two or three method parameters which are described in the following:
- An optional error message that's shown when our assertion fails.
- The actual value or object.
- A
Matcher
object that specifies the expected value. We can create newMatcher
objects by using thestatic
factory methods provided by theorg.hamcrest.Matchers
class.
Next, we will take a look at some examples which demonstrate how we can write assertions with Hamcrest. Let’s start by finding out how we can write assertions for boolean
values.
Asserting Boolean Values
If we want to verify that a boolean
value is true
, we have to create our Hamcrest matcher by invoking the is()
method of the Matchers
class. In order words, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.Matchers.is; import static org.hamcrest.MatcherAssert.assertThat; @DisplayName("Write assertions for booleans") class BooleanAssertionTest { @Nested @DisplayName("When boolean is true") class WhenBooleanIsTrue { @Test @DisplayName("Should be true") void shouldBeTrue() { assertThat(true, is(true)); } } }
If we want to verify that a boolean
value is false
, we have to create our Hamcrest matcher by invoking the is()
method of the Matchers
class. In order words, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.Matchers.is; import static org.hamcrest.MatcherAssert.assertThat; @DisplayName("Write assertions for booleans") class BooleanAssertionTest { @Nested @DisplayName("When boolean is false") class WhenBooleanIsFalse { @Test @DisplayName("Should be false") void shouldBeFalse() { assertThat(false, is(false)); } } }
Let's move on and find out how we can verify that an object is null
or isn't null
.
Asserting That an Object Is Null or Isn't Null
If we want to verify that an object is null
, we have to create our Hamcrest matcher by invoking the nullValue()
method of the Matchers
class. In order words, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.nullValue; @DisplayName("Writing assertions for objects") class ObjectAssertionTest { @Nested @DisplayName("When object is null") class WhenObjectIsNull { @Test @DisplayName("Should be null") void shouldBeNull() { assertThat(null, nullValue()); } } }
If we want to verify that an object isn't null
, we have to create our Hamcrest matcher by invoking the notNullValue()
method of the Matchers
class. In order words, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; @DisplayName("Writing assertions for objects") class ObjectAssertionTest { @Nested @DisplayName("When object is not null") class WhenObjectIsNotNotNull { @Test @DisplayName("Should not be null") void shouldNotBeNull() { assertThat(new Object(), notNullValue()); } } }
Next, we will find out how we can verify that two objects (or values) are equal or aren't equal.
Asserting That Two Objects or Values Are Equal
If we want to verify that the expected value (or object) is equal to the actual value (or object), we have to create our Hamcrest matcher by invoking the equalTo()
method of the Matchers
class. For example, if we want to compare two Integer
objects, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @DisplayName("Writing assertions for objects") class ObjectAssertionTest { @Nested @DisplayName("When two objects are equal") class WhenTwoObjectsAreEqual { @Nested @DisplayName("When objects are integers") class WhenObjectsAreIntegers { private final Integer ACTUAL = 9; private final Integer EXPECTED = 9; @Test @DisplayName("Should be equal") void shouldBeEqual() { assertThat(ACTUAL, equalTo(EXPECTED)); } } } }
If we want to verify that the expected value (or object) isn't equal to the actual value (or object), we have to create our Hamcrest matcher by invoking the not()
method of the Matchers
class. For example, if we want to compare two Integer
objects, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.not; @DisplayName("Writing assertions for objects") class ObjectAssertionTest { @Nested @DisplayName("When two objects aren't equal") class WhenTwoObjectsAreNotEqual { @Nested @DisplayName("When objects are integers") class WhenObjectsAreIntegers { private final Integer ACTUAL = 9; private final Integer EXPECTED = 4; @Test @DisplayName("Should not be equal") void shouldNotBeEqual() { assertThat(ACTUAL, not(EXPECTED)); } } } }
Let's move on and find out how we can write assertions for object references.
Asserting Object References
If we want to ensure that two objects refer to the same object, we have to create our Hamcrest matcher by invoking the sameInstance()
method of the Matchers
class. In order words, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.sameInstance; @DisplayName("Writing assertions for objects") class ObjectAssertionTest { @Nested @DisplayName("When two objects refer to the same object") class WhenTwoObjectsReferToSameObject { private final Object ACTUAL = new Object(); private final Object EXPECTED = ACTUAL; @Test @DisplayName("Should refer to the same object") void shouldReferToSameObject() { assertThat(ACTUAL, sameInstance(EXPECTED)); } } }
If we want to ensure that two objects don't refer to the same object, we have to reverse the expectation specified by the sameInstance()
method by using the not()
method of the Matchers
class. In order words, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.sameInstance; @DisplayName("Writing assertions for objects") class ObjectAssertionTest { @Nested @DisplayName("When two objects don't refer to the same object") class WhenTwoObjectsDoNotReferToSameObject { private final Object ACTUAL = new Object(); private final Object EXPECTED = new Object(); @Test @DisplayName("Should not refer to the same object") void shouldNotReferToSameObject() { assertThat(ACTUAL, not(sameInstance(EXPECTED))); } } }
Next, we will find out how we can verify that two arrays are equal.
Asserting That Two Arrays Are Equal
If we want to verify that two arrays are equal, we have to create our Hamcrest matcher by invoking the equalTo()
method of the Matchers
class. For example, if we want verify that two int
arrays are equal, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @DisplayName("Write assertions for arrays") class ArrayAssertionTest { @Nested @DisplayName("When arrays contain integers") class WhenArraysContainIntegers { final int[] ACTUAL = new int[]{2, 5, 7}; final int[] EXPECTED = new int[]{2, 5, 7}; @Test @DisplayName("Should contain the same integers") void shouldContainSameIntegers() { assertThat(ACTUAL, equalTo(EXPECTED)); } } }
- They are both
null
or empty. - Both arrays contain the "same" objects or values. To be more specific, JUnit 5 iterates both arrays one element at a time and ensures that the elements found from the given index are equal.
Let's move on and find out how we can write assertions for lists.
Asserting Lists
If we want to write an assertion which verifies that the size of a list is correct, we have to create our Hamcrest matcher by invoking the hasSize()
method of the Matchers
class. For example, if we want to verify that the size of a list is 2, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; @DisplayName("Writing assertions for lists") class ListAssertionTest { @Nested @DisplayName("When we write assertions for elements") class WhenWeWriteAssertionsForElements { private Object first; private Object second; private List<Object> list; @BeforeEach void createAndInitializeList() { first = new Object(); second = new Object(); list = Arrays.asList(first, second); } @Test @DisplayName("Should contain two elements") void shouldContainTwoElements() { assertThat(list, hasSize(2)); } } }
If we want to verify that the list contains only the expected elements in the given order, we have to create our Hamcrest matcher by invoking the contains()
method of the Matchers
class. For example, if we want to verify that our list contains the correct elements in the given order, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; @DisplayName("Writing assertions for lists") class ListAssertionTest { @Nested @DisplayName("When we write assertions for elements") class WhenWeWriteAssertionsForElements { private Object first; private Object second; private List<Object> list; @BeforeEach void createAndInitializeList() { first = new Object(); second = new Object(); list = Arrays.asList(first, second); } @Test @DisplayName("Should contain the correct elements in the given order") void shouldContainCorrectElementsInGivenOrder() { assertThat(list, contains(first, second)); } } }
If we want to verify that the list contains only the expected elements in any order, we have to create our Hamcrest matcher by invoking the containsInAnyOrder()
method of the Matchers
class. For example, if we want to verify that our list contains the correct elements in any order, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; @DisplayName("Writing assertions for lists") class ListAssertionTest { @Nested @DisplayName("When we write assertions for elements") class WhenWeWriteAssertionsForElements { private Object first; private Object second; private List<Object> list; @BeforeEach void createAndInitializeList() { first = new Object(); second = new Object(); list = Arrays.asList(first, second); } @Test @DisplayName("Should contain the correct elements in any order") void shouldContainCorrectElementsInAnyOrder() { assertThat(list, containsInAnyOrder(second, first)); } } }
If we want to ensure that a list contains the given element, we have to create our Hamcrest matcher by invoking the hasItem()
method of the Matchers
class. For example, if we want to verify that our list contains the Object
that's stored in the field called first
, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; @DisplayName("Writing assertions for lists") class ListAssertionTest { @Nested @DisplayName("When we write assertions for elements") class WhenWeWriteAssertionsForElements { private Object first; private Object second; private List<Object> list; @BeforeEach void createAndInitializeList() { first = new Object(); second = new Object(); list = Arrays.asList(first, second); } @Test @DisplayName("Should contain a correct element") void shouldContainCorrectElement() { assertThat(list, hasItem(first)); } } }
If we want to ensure that a list doesn't contain an element, we have to reverse the expectation specified by the hasItem()
method by using the not()
method of the Matchers
class. In order words, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.not; @DisplayName("Writing assertions for lists") class ListAssertionTest { @Nested @DisplayName("When we write assertions for elements") class WhenWeWriteAssertionsForElements { private Object first; private Object second; private List<Object> list; @BeforeEach void createAndInitializeList() { first = new Object(); second = new Object(); list = Arrays.asList(first, second); } @Test @DisplayName("Should not contain an incorrect element") void shouldNotContainIncorrectElement() { assertThat(list, not(hasItem(new Object()))); } } }
If we want to verify that two lists are deeply equal, we have to create our Hamcrest matcher by invoking the equalTo()
method of the Matchers
class. For example, if we want verify that two Integer
lists are deeply equal, we have to use this assertion:
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @DisplayName("Writing assertions for lists") class ListAssertionTest { @Nested @DisplayName("When we compare two lists") class WhenWeCompareTwoLists { private final List<Integer> ACTUAL = Arrays.asList(1, 2, 3); private final List<Integer> EXPECTED = Arrays.asList(1, 2, 3); @Test @DisplayName("Should contain the same elements") void shouldContainSameElements() { assertThat(ACTUAL, equalTo(EXPECTED)); } } }
- They are both
null
or empty. - Both lists contain the "same" objects or values. To be more specific, JUnit 5 iterates both lists one element at a time and ensures that the elements found from the given index are equal.
Next, we will find out how we can write assertions for maps.
Asserting Maps
If we want to verify that a map contains the given key, we have to create our Hamcrest matcher by invoking the hasKey()
method of the Matchers
class. In other words, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasKey; @DisplayName("Writing assertions for maps") class MapAssertionTest { private static final String KEY = "key"; private static final String VALUE = "value"; private Map<String, String> map; @BeforeEach void createAndInitializeMap() { map = new HashMap<>(); map.put(KEY, VALUE); } @Nested @DisplayName("When we check if the map contains the given key") class WhenWeCheckIfMapContainsGivenKey { @Test @DisplayName("Should contain the correct key") void shouldContainCorrectKey() { assertThat(map, hasKey(KEY)); } } }
If we want to verify that a map doesn't contain the given key, we have to reverse the expectation specified by the hasKey()
method by using the not()
method of the Matchers
class. In other words, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasKey; import static org.hamcrest.Matchers.not; @DisplayName("Writing assertions for maps") class MapAssertionTest { private static final String INCORRECT_KEY = "incorrectKey"; private static final String KEY = "key"; private static final String VALUE = "value"; private Map<String, String> map; @BeforeEach void createAndInitializeMap() { map = new HashMap<>(); map.put(KEY, VALUE); } @Nested @DisplayName("When we check if the map contains the given key") class WhenWeCheckIfMapContainsGivenKey { @Test @DisplayName("Should not contain the incorrect key") void shouldNotContainIncorrectKey() { assertThat(map, not(hasKey(INCORRECT_KEY))); } } }
If we want to ensure that a map contains the correct value, we have to create our Hamcrest matcher by invoking the hasEntry()
method of the Matchers
class. In other words, we have to use this assertion:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasEntry; @DisplayName("Writing assertions for maps") class MapAssertionTest { private static final String KEY = "key"; private static final String VALUE = "value"; private Map<String, String> map; @BeforeEach void createAndInitializeMap() { map = new HashMap<>(); map.put(KEY, VALUE); } @Nested @DisplayName("When we check if the map contains the correct value") class WhenWeCheckIfMapContainsCorrectValue { @Test @DisplayName("Should contain the correct value") void shouldContainCorrectValue() { assertThat(map, hasEntry(KEY, VALUE)); } } }
Let's move on and find out how we can combine multiple Hamcrest matchers.
Combining Hamcrest Matchers
We can now write basic assertions with Hamcrest. However, sometimes we have to combine multiple Hamcrest matchers. In fact, we already did this when we reversed the expectation of a Hamcrest matcher by invoking the not()
method of the Matchers
class.
Next, we will take a look at two examples which demonstrate how we can combine Hamcrest matchers when we are writing assertions for a Person
object. The source code of the Person
class looks as follows:
public class Person { private String firstName; private String lastName; public Person() {} public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setLastName(String lastName) { this.lastName = lastName; } }
As we can see, if we want to verify that a person has the correct name, we have to ensure that the asserted Person
object has the correct first and last name. When we write this assertion, we have to create the Hamcrest matcher that's passed to the assertThat()
method by using these Hamcrest Matchers:
- The
allOf()
method of theMatchers
class returns a Hamcrest matcher which expects that the asserted object matches with all specified Hamcrest matchers. - The
hasProperty()
method of theMatchers
class returns a matcher which allows us to write assertions for the properties of the asserted object. - The
equalTo()
method of theMatchers
class returns a matcher which allows us to verify that the actual property value is equal to the expected value.
After we have written our assertion, it looks as follows:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; @DisplayName("Combine multiple assertions") class CombineAssertionsTest { private static final String FIRST_NAME = "Jane"; private static final String LAST_NAME = "Doe"; private Person person; @BeforeEach void createPerson() { person = new Person(); person.setFirstName(FIRST_NAME); person.setLastName(LAST_NAME); } @Test @DisplayName("Should have the correct name") void shouldHaveCorrectName() { assertThat(person, allOf( hasProperty("firstName", equalTo(FIRST_NAME)), hasProperty("lastName", equalTo(LAST_NAME)) )); } }
On the other hand, if we want to verify that a person has the correct first name or last name, we have to create the Hamcrest matcher that's passed to the assertThat()
method by using these Hamcrest Matchers:
- The
anyOf()
method of theMatchers
class returns a Hamcrest matcher which expects that the asserted object matches with any specified Hamcrest matcher. - The
hasProperty()
method of theMatchers
class returns a matcher which allows us to write assertions for the properties of the asserted object. - The
equalTo()
method of theMatchers
class returns a matcher which allows us to verify that the actual property value is equal to the expected value.
After we have written our assertion, it looks as follows:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; @DisplayName("Combine multiple assertions") class CombineAssertionsTest { private static final String FIRST_NAME = "Jane"; private static final String LAST_NAME = "Doe"; private Person person; @BeforeEach void createPerson() { person = new Person(); person.setFirstName(FIRST_NAME); person.setLastName(LAST_NAME); } @Test @DisplayName("Should have correct first name or last name") void shouldHaveCorrectFirstNameOrLastName() { assertThat(person, anyOf( hasProperty("firstName", equalTo(FIRST_NAME)), hasProperty("lastName", equalTo(LAST_NAME)) )); } }
Matchers
class can take a Hamcrest matcher (or matchers) as a method parameter. That's why I recommend that you take a look at its documentation when it seems that you cannot write the assertion you need. The odds are that you can write it by combining multiple Hamcrest matchers.
Next, we will find out how we can provide a custom error message that's shown when our assertion fails.
Providing a Custom Error Message
As we remember, if we want to specify a custom error message that's shown when our assertion fails, we have to pass this message as the first method parameter of the assertThat()
method. We can create this error message by using one of these two options:
- If the error message has no parameters, we should use a
String
literal. - If the error message has parameters, we should use the
static format()
method of theString
class.
For example, if we want to create an error message that's shown when the asserted list doesn't contain the given element, we have to create an assertion that looks as follows:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; @DisplayName("Writing assertions for lists") class ListAssertionTest { @Nested @DisplayName("When we write assertions for elements") class WhenWeWriteAssertionsForElements { private Object first; private Object second; private List<Object> list; @BeforeEach void createAndInitializeList() { first = new Object(); second = new Object(); list = Arrays.asList(first, second); } @Test @DisplayName("Should contain a correct element") void shouldContainCorrectElementWithCustomErrorMessage() { assertThat(String.format( "The list doesn't contain the expected object: %s", first ), list, hasItem(first) ); } } }
We can now write basic assertions with Hamcrest, combine multiple Hamcrest matchers, and provide a custom error message that's shown when an assertion fails.
Let's summarize what we learned from this blog post.
Summary
This blog post has taught us four things:
- Before we can write assertions with Hamcrest, we have to ensure that the
hamcrest-library
dependency is found from the classpath. - If we want to write assertions with Hamcrest, we have to use the
assertThat()
method of theorg.hamcrest.MatcherAssert
class. - If we want to provide a custom error message that's shown when an assertion fails, we have to pass this error message as the first method parameter of the
assertThat()
method. - Some methods of the
Matchers
class can take a Hamcrest matcher (or matchers) as a method parameter. We can combine multiple Hamcrest matchers by using these methods.
P.S. You can get the example application of this blog post from Github
Is there an easy way for asserting all fields of object (via getters) are not null ?
If you want to use Hamcrest, you can combine multiple assertions by using the
allOf()
method of theMatchers
. Also, because you want to ensure that all field values of your object are null, you have to write the actual assertions by using thenullValue()
method of theMatchers
class.That being said, I think that you should take a look at AssertJ. It allows you to write so called soft assertions that help you to solve your problem in a elegant way.
The difference between these two methods is that AssertJ runs all assertions (if you use soft assertions) before it reports the results. In other words, if a test case fails, you can see all assertions failures. If you use Hamcrest, you can see only the first assertion failure. This means that you might have to run your test case multiple times (and fix your code) before it passes.