Hamcrest matchers are the assertion engine of REST Assured. They are what let you write .body("name", equalTo("John")) instead of extracting the value and using assertEquals. The import is import static org.hamcrest.Matchers.*. Let us go through every matcher you will actually use.
| Matcher | What It Checks | Example |
|---|---|---|
| equalTo(value) | Exact match | .body("name", equalTo("John")) |
| not(equalTo(value)) | Not equal | .body("status", not(equalTo("deleted"))) |
| nullValue() | Value is null | .body("deletedAt", nullValue()) |
| notNullValue() | Value is not null | .body("id", notNullValue()) |
| is(value) | Same as equalTo (alias) | .body("active", is(true)) |
| Matcher | What It Checks | Example |
|---|---|---|
| containsString("text") | Contains substring | .body("message", containsString("success")) |
| startsWith("text") | Starts with prefix | .body("email", startsWith("admin")) |
| endsWith("text") | Ends with suffix | .body("email", endsWith("@gmail.com")) |
| equalToIgnoringCase("text") | Case-insensitive match | .body("status", equalToIgnoringCase("ACTIVE")) |
| emptyString() | Empty string "" | .body("error", emptyString()) |
| blankOrNullString() | Blank, empty, or null | .body("notes", blankOrNullString()) |
| Matcher | What It Checks | Example |
|---|---|---|
| greaterThan(n) | Value > n | .body("price", greaterThan(0)) |
| greaterThanOrEqualTo(n) | Value >= n | .body("stock", greaterThanOrEqualTo(1)) |
| lessThan(n) | Value < n | .body("discount", lessThan(100)) |
| lessThanOrEqualTo(n) | Value <= n | .body("rating", lessThanOrEqualTo(5)) |
| Matcher | What It Checks | Example |
|---|---|---|
| hasSize(n) | Array has n elements | .body("items", hasSize(10)) |
| hasItem(value) | Array contains this value | .body("tags", hasItem("java")) |
| hasItems(v1, v2) | Array contains all these values | .body("roles", hasItems("admin", "user")) |
| everyItem(matcher) | Every element matches | .body("prices", everyItem(greaterThan(0))) |
| empty() | Collection is empty | .body("errors", empty()) |
| hasEntry(key, value) | Map has this key-value pair | .body("config", hasEntry("debug", false)) |
| hasKey(key) | Map/object has this key | .body("$", hasKey("userId")) |
@Test
public void testCombinedMatchers() {
given()
.when()
.get("/posts")
.then()
.statusCode(200)
// allOf — ALL matchers must pass
.body("size()", allOf(greaterThan(50), lessThan(200)))
// anyOf — at least ONE matcher must pass
.body("[0].userId", anyOf(equalTo(1), equalTo(2)))
// not — negation
.body("[0].title", not(emptyString()));
}
@Test
public void testEveryItemMatcher() {
given()
.queryParam("userId", 1)
.when()
.get("/posts")
.then()
.statusCode(200)
.body("userId", everyItem(equalTo(1))) // Every userId must be 1
.body("title", everyItem(notNullValue())) // No null titles
.body("id", everyItem(greaterThan(0))); // All IDs positive
}Key Point: You do not need to memorize every matcher. Bookmark this lesson. The ones you will use 90% of the time: equalTo, notNullValue, hasSize, containsString, greaterThan, everyItem, and hasItem.
In IntelliJ, type Matchers. and press Ctrl+Space to see all available matchers. The autocomplete is your cheat sheet while coding.
Q: What Hamcrest matchers do you commonly use in REST Assured?
A: My go-to matchers: equalTo() for exact value matching, notNullValue() for presence checks, hasSize() for array length, containsString() for partial string matching, greaterThan()/lessThan() for numeric comparisons, everyItem() for validating all elements in an array, and hasItem()/hasItems() for checking array contents. I also use allOf() and anyOf() to combine multiple matchers. For example, allOf(greaterThan(0), lessThan(100)) checks a value is between 0 and 100. Import them with import static org.hamcrest.Matchers.*.
Key Point: Hamcrest matchers let you write readable assertions. The 90% set: equalTo, notNullValue, hasSize, containsString, greaterThan, everyItem, hasItem. Combine with allOf/anyOf/not.