How to Perform Response Verification in REST-Assured Java for API Testing: Part 2
Master REST-Assured response verification in Java with Hamcrest Matchers, JSON assertions, API validations, and real-world examples.
Join the DZone community and get the full member experience.
Join For FreeAPI testing is an essential part of modern software development. While sending requests and receiving responses is straightforward, the real value of API automation comes from response verification. A test is meaningful only when it validates that the API returns the correct data, structure, status codes, and business rules.
In Java-based API automation, REST Assured combined with Hamcrest Matchers provides a clean and expressive way to verify API responses. These matchers help testers write readable assertions that validate numbers, strings, arrays, JSON objects, and collections with minimal code.
This tutorial explains how to perform response verification in REST Assured using the following Hamcrest Matchers:
- Numeric
- String
- Collections
- JSON Object validations
- Negative validation
By the end of this article, you will be able to write powerful and maintainable API assertions in your automation tests.
If you have not checked, click here to read Part 1 of this blog post.
What Is Response Verification in API Testing?
Response verification is the process of validating the API response returned from the server. This includes checking status codes, response body values, JSON structure, headers, data types, arrays, objects, and business validations.
The verification includes checking:
- Does the API response return a 200 OK status code?
- Does the response contain the expected value for the fields?
- Is the list size greater than zero?
- Does every object contain a specific key?
Without assertions, an API test is just sending requests and receiving responses without actually checking whether the API behaves correctly.
How to Use Hamcrest Matchers With Rest-Assured for Response Verification in REST-Assured Java
Hamcrest Matchers improve readability and make assertions more expressive. To use Hamcrest, the following dependency should be added to the pom.xml in the Maven project:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
Numeric Matchers
In this section, we’ll learn to use numeric matchers in Rest-Assured tests, including greaterThan (), greaterThanOrEqualTo(), lessThan(), and lessThanOrEqualTo(). These assertions help in validating numerical values returned in API responses.
Using greaterThan() and greaterThanOrEqualTo()
The greaterThan() matcher verifies that a numeric value is greater than the expected value.
Similarly, the greaterThanOrEqualTo() matcher validates that the value is either greater than or equal to the expected number.
@Test
public void testGreaterThanAssertions () {
given ().when ()
.get ("https://api.restful-api.dev/objects")
.then ()
.statusCode (200)
.and ()
.assertThat ()
.body ("[2].data['capacity GB']", greaterThan (500))
.body ("[5].data['price']", greaterThanOrEqualTo (120));
}
In this test, the greaterThan () method from the Hamcrest library verifies that the capacity GB value in the third JSON object is greater than 500. The greaterThanOrEqualTo matcher checks whether the price value in the sixth object is 120 or more.
These assertions help validate numerical values returned by the API without relying on exact matches. Numeric matchers are useful for testing values such as prices, counts, capacities, and response times.
Using lessThan() and lessThanOrEqualTo()
The lessThan() matcher validates that the value is below the expected number. Likewise, the lessThanOrEqualTo() matcher validates that the number is less than or equal to the expected value.
@Test
public void testLessThanAssertions () {
given ().when ()
.log ()
.all ()
.get ("https://api.restful-api.dev/objects")
.then ()
.log ()
.all ()
.statusCode (200)
.and ()
.assertThat ()
.body ("[4].data['price']", lessThan (700f))
.body ("[6].data['year']", lessThanOrEqualTo (2019));
}
In this test, the lessThan() method from the Hamcrest library verifies that the price value in the fifth JSON object is less than 700, while lessThanOrEqualTo() checks whether the year value in the seventh object is 2019 or lower.
The value 700f is written with the “f” suffix because the API returns the price as a float, and using “f” ensures the expected value is also treated as a float during comparison.
These assertions help ensure that the numerical values returned by the API remain within the expected limits.
String Matchers
In this section, we’ll learn to use String matchers in Rest-Assured tests, including equalToIgnoringCase(), containsString(), startsWith(), endsWith(), and equalToCompressingWhiteSpace(). These assertions are useful for validating text-based values returned in API responses.
@Test
public void testStringAssertion() {
given ().when ()
.log ()
.all ()
.queryParam ("id", 3)
.get ("https://api.restful-api.dev/objects")
.then ()
.log ()
.all ()
.statusCode (200)
.and ()
.assertThat ()
.body ("[0].name", equalTo ("Apple iPhone 12 Pro Max"))
.body ("[0].name", equalToIgnoringCase ("ApPLE IPhone 12 pro MAX"))
.body ("[0].data.color", containsString ("White"))
.body ("[0].name", startsWith ("A"))
.body ("[0].name", endsWith ("x"))
.body ("[0].name", equalToCompressingWhiteSpace (" Apple iPhone 12 Pro Max "));
}
The testStringAssertion() method demonstrates different ways to validate string values in an API response using REST Assured and Hamcrest matchers:
- body(“[0].name”, equalTo (“Apple iPhone 12 Pro Max”)): Verifies that the name field exactly matches the expected string, including the letter casing and spaces.
- body(“[0].name”, equalToIgnoringCase(“ApPLE IPhone 12 pro MAX”)): Validates the string value while ignoring differences in uppercase and lowercase characters.
- body(“[0].data.color”, containsString(“White”)): Verifies whether the color field contains the text White anywhere within the string.
- body(“[0].name”, startsWith(“A”)): Verifies that the name field begins with the letter “A”.
- body(“[0].name”, endsWith(“x”)): Validates that the name field ends with the letter “x”.
- body(“[0].name”, equalToCompressingWhiteSpace(“ Apple iPhone 12 Pro Max ”)): Compares the string values after removing extra spaces and compressing multiple whitespaces into a single space, making the assertion more flexible for formatting differences.
These matchers help verify exact text, partial text, prefixes, suffixes, case sensitivity, and whitespace formatting.
Collection Matchers
In this section, we’ll learn to use collection matchers in Rest-Assured tests, including hasSize(), hasItem(), hasKey(), and everyItem(hasKey()).
These assertions help in validating arrays and collections returned in API responses, such as verifying the number of items, checking for specific values, and ensuring required keys are present.
Using hasSize() and hasItem() matchers
@Test
public void testHasSizeAndHasItem () {
given ().when ()
.queryParam ("id", 3)
.queryParam ("id", 5)
.get ("https://api.restful-api.dev/objects")
.then ()
.statusCode (200)
.and ()
.assertThat ()
.body ("$", hasSize (2))
.body ("name", hasItem ("Apple iPhone 12 Pro Max"));
}
The testHasSizeAndHasItem() method demonstrates how to validate collections and arrays returned in the API response using Hamcrest matchers in REST Assured.
It uses the hasSize() and hasItem() methods from the Hamcrest matchers for verifying the size of the response collection and whether specific items exist within it.
- body(“$”, hasSize(2)): The hasSize() matcher verifies that the response array contains exactly “2” objects. As the request is sent with two query params (id=3 and id=5), the API is expected to return two matching records.
- body(“name”, hasItem(“Apple iPhone 12 Pro Max”)): The hasItem() matcher checks whether the name collection in the response contains the value “Apple iPhone 12 Pro Max”. This assertion helps in validating that a specific item exists within the returned response.
Using hasKey(), and everyItem(hasKey()) matchers
@Test
public void testHasKeyAssertions () {
given ().when ()
.log ()
.all ()
.queryParam ("id", 3)
.get ("https://api.restful-api.dev/objects")
.then ()
.log ()
.all ()
.statusCode (200)
.and ()
.assertThat ()
.body ("$", everyItem (hasKey ("id")))
.body ("[0].data", hasKey ("capacity GB"))
.body ("$", everyItem (hasKey ("name")));
}
The testHasKeyAssertions() method shows how to validate the presence of keys in the JSON objects returned by an API response. The hasKey() matcher is commonly used to ensure that the required fields are present in the response.
- body(“$”, everyItem(hasKey(“id”))): The everyItem(hasKey()) assertion verifies that every object in the response array contains the “id” key. This helps ensure consistency across all returned objects.
- body(“[0].data”, hasKey(“capacity GB”)): The hasKey() matcher checks whether the data object of the first response item contains the key “capacity GB”. This assertion validates the presence of a specific field inside a nested JSON object.
- body(“$”, everyItem(hasKey(“name”))): This assertion verifies that all objects in the response array contain the name key. It ensures that the expected field is available in every returned record in the API response.
Negative Validations
Negative validation in Rest-Assured is commonly performed using the not() negation matcher from Hamcrest to verify that an API response does not contain certain values or conditions.
Using the not() matcher, the condition can be inverted, and accordingly, the assertion validates that the specified value or condition is not present in the API response.
@Test
public void testNotAssertions () {
given ().when ()
.log ()
.all ()
.queryParam ("id", 3)
.get ("https://api.restful-api.dev/objects")
.then ()
.log ()
.all ()
.statusCode (200)
.and ()
.assertThat ()
.body ("$", not (emptyArray ()))
.body ("[0].id", notNullValue ())
.body ("[0].name", not (equalTo ("Samsung")))
.body ("[0].data['capacity GB']", not (greaterThan (550)));
}
The testNotAssertions() method demonstrates how to perform negative validations in Rest-Assured using the not() matcher and related assertions.
- body(“$”, not(emptyArray())): This assertion verifies that the response array is not empty and contains at least one object.
- body(“[0].id”, notNullValue()): The notNullValue() matcher verifies that the “id” field in the first response object is not null.
- body(“[0].name”, not (equalTO (“Samsung”))): This assertion validates that the name field is not equal to “Samsung”.
- body(“[0].data[‘capacity GB’]”, not(greaterThan(550))): The not(greaterThan()) assertion verifies that the “capacity GB” value is not greater than 550. This means that the value should be less than or equal to 550.
Summary
Response verification is what transforms an API test from simply sending requests into actually validating application behavior. In this tutorial, we explored how REST Assured and Hamcrest Matchers make assertions more readable and powerful by validating numbers, strings, arrays, JSON keys, and response structures.
In my experience, learning these matchers significantly improves the quality and maintainability of API automation frameworks. Numeric, String, Collection, and Negative Matchers are especially useful in real-world testing because they help create validations that are both flexible and easy to understand, making debugging and test maintenance much simpler over time.
Happy testing!!
Published at DZone with permission of Faisal Khatri. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments