We can also choose to use the Hamcrest assertion library in our code, either instead of the JUnit assertions or in addition to them. Hamcrest includes some very helpful assertions that are not part of JUnit, and also includes version for many languages, including both Java and Python. Most of the autograders in previous Computational Core courses are written with the Hamcrest assertion library!
Basic Assertions
Hamcrest uses a single basic assertion method called assertThat()
to perform all assertions. It comes in two basic forms:
assertThat(actual, matcher)
- asserts thatactual
passes thematcher
.assertThat(message, actual, matcher)
- asserts thatactual
passes thematcher
. If not, it will printmessage
as part of the failure.
The real power of Hamcrest lies in the use of Matchers, which are used to determine if the actual
value passes a test. If not, then the assertThat
method will fail, just like a JUnit assertion.
For example, to test if an actual value returned by a fictional calculator
object is equal to an expected value, we could use this statement:
assertThat(calculator.add(1, 3), is(4));
As we can see, reading this statement out loud tells us everything we need to know: “Assert that calculator.add(1, 3)
is 4!”
Here are a few of the most commonly used Hamcrest matchers, as listed in the Hamcrest Tutorial. The full list of matchers can be found in the Matchers class in the Hamcrest documentation:
is(expected)
- a shortcut for equality - an example of syntactic sugar as discussed below.equalTo(expected)
- will call theactual.equals(expected)
method to test equalityisCompatibleType(type)
- can be used to check if an object is the correct type, helpful for testing inheritancenullValue()
- check if the value isnull
notNullValue()
- check if the value is notnull
sameInstance(expected)
- checks if two objects are the same instancehasEntry(entry)
,hasKey(key)
,hasValue(value)
- matchers for working with Maps such as HashMapshasItem(item)
- matcher for Collections such as LinkedListhasItemInArray(item)
- matcher for arrayscloseTo(expected, delta)
- matcher for testing floating-point values within a rangegreaterThan(expected)
,greaterThanOrEqualTo(expected)
,lessThan(expected)
,lessThanOrEqualTo(expected)
- numerical matchersequalToIgnoringCase(expected)
,equalToIgnoringWhiteSpace(expected)
,containsString(string)
,endsWith(string)
,startsWith(string)
- string matchersallOf(matcher1, matcher2, ...)
,anyOf(matcher1, matcher2, ...)
,not(matcher)
- boolean logic operators used to combine multiple matchers
Syntactic Sugar
Hamcrest includes a helpful matcher called is
that makes some assertions more easily readable. For example, each of these assertion statements from the Hamcrest Tutorial all test the same thing:
assertThat(theBiscuit, equalTo(myBiscuit));
assertThat(theBiscuit, is(equalTo(myBiscuit)));
assertThat(theBiscuit, is(myBiscuit));
By including the is
matcher, we can make our assertions more readable. We call this syntactic sugar since it doesn’t add anything new to our language structure, but it can help make it more readable.
Examples
There are lots of great examples of how to use Hamcrest available on the web. Here are a couple that are worth checking out:
- Using Hamcrest for Testing - Tutorial from Vogella
- Testing with Hamcrest from Baeldung