Hamcrest: Core Matchers & assertThat
Hamcrest is a library of composable matcher objects for writing expressive, readable test assertions -- it doesn't run tests itself, it plugs into assertThat() calls from JUnit, TestNG, or similar test runners.
assertThat and Basic Matchers
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
@Test
void basicMatchers() {
int result = calculate();
// is() is a pure readability wrapper -- is(5) == is(equalTo(5))
assertThat(result, is(5));
assertThat(result, equalTo(5));
// On failure, produces a specific message automatically:
// "expected <5> but was <3>" -- unlike assertTrue(result == 5),
// which would just report "expected true but was false"
assertThat(result, greaterThan(0));
assertThat(result, not(equalTo(0)));
String name = getName();
assertThat(name, containsString("Ali")); // substring match
assertThat(name, startsWith("Al"));
assertThat(name, equalToIgnoringCase("ALICE"));
Double pi = computePi();
// Floating point equality is unreliable -- use a tolerance
assertThat(pi, closeTo(3.14159, 0.001));
}Combinators: allOf, anyOf, not
@Test
void combinedMatchers() {
int age = getAge();
// All conditions must match
assertThat(age, allOf(greaterThan(0), lessThan(120)));
// At least one condition must match
assertThat(status, anyOf(equalTo("ACTIVE"), equalTo("PENDING")));
// Negation
assertThat(list, not(empty()));
assertThat(value, not(nullValue()));
// Type checking
assertThat(exception, instanceOf(IllegalArgumentException.class));
// Testing a Java Bean property via reflection
assertThat(person, hasProperty("name", equalTo("Alice")));
}Why Matcher Assertions Over Plain Booleans
assertThat(value, greaterThan(5)) reports "expected a value greater than <5> but was <3>" -- assertTrue(value > 5) just reports "expected true but was false", losing context.
Matchers are composable -- allOf/anyOf/not build complex conditions readably instead of a tangled boolean expression.
Prefer specific matchers over generic ones (notNullValue(), anything()) -- weak assertions pass even when the actual value is wrong, giving false confidence.
JUnit 5 dropped its bundled Hamcrest dependency -- add org.hamcrest:hamcrest explicitly to keep using assertThat() with Hamcrest matchers.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free