This tutorial discusses about RESTAssured, a Testing framework that is used by several frameworks (including Quarkus) to test specifically REST applications.
REST Assured is a Java API that can be used to validate RESTful services through its fluent DSL (Domain specific Languages) that describes a connection to an HTTP endpoint and expected results.
Here is a REST Assured Hello World example:
import static com.jayway.restassured.RestAssured.given;
import org.junit.Test;
public class MinimalRestAssured {
@Test
public void checkSiteIsUp() {
given().when().get("http://www.acme.com").then().statusCode(200);
}
}
This minimal example shows how to connect to an HTTP resource through a GET call and verify that the HTTP code 200/success is returned. Notice that we don't need to use typical assert expressions (like JUnit classes do) as this si done behind the hoods by RESTAssured if there is a mismatch between your expression and the result. Now let's see a more complex example where we check the body returned as JSON. In order to do that, we first need to import some more classes:
import io.restassured.RestAssured.*
import io.restassured.matcher.RestAssuredMatchers.*
import org.hamcrest.Matchers.*
Now let's see practical example.
Suppose you have the following JSON returned by the URI "/cars" :
{
"year": "2001",
"make": "Ford",
"model": "Coupe"
}
You can verify that URI returns a status code of 200 and the body content using this fluent API:
@Test
public void testCustomerService() {
given()
.when().get("/cars")
.then()
.statusCode(200)
.body(containsString("Ford"),
containsString("Coupe"));
}
You can also verify exact values:
@Test
public void testCustomerService() {
given()
.when().get("/cars")
.then()
.statusCode(200)
.body("year", is(1987));
}
RESTAssured using Parameters
What if your REST Test uses parameters? Here is how you can Test against Path Params:
@Test
public void testListOfUsers() {
given()
.contentType(ContentType.JSON)
.pathParam("id", "12345")
.when()
.get("/users/{id}")
.then()
.statusCode(200)
.body("firstName", equalTo("John"))
.body("Surname", equalTo("Doe"));
}
And here is how you can test agains Query Parameters using as bonus also an Header Verification:
@Test
public void testListOfUsers() {
given()
.header("Authorization", authorizationHeader)
.accept(JSON)
.queryParam("id", "1")
.when()
.get("/users")
.then()
.statusCode(200)
.body("firstName", equalTo("John"))
.body("Surname", equalTo("Doe"));
}
How to validate a response which contains an array of data
Applications which are producing tabular data from a Database, typically a response with an Array of JSON objects. To validate the content of the response, you can reference the single array data as in the following example:
@Test
public void testListOfUsers() {
RestAssured.given()
.when().get()
.then()
.statusCode(200)
.body("$.size()", is(3),
"[0].id", is(1),
"[0].name", is("Batman"),
"[1].id", is(2),
"[1].name", is("Superman"),
"[2].id", is(3),
"[2].name", is("Wonder woman")
);
}
Extracting Manually the Response
In some cases, it could be required to fetch the JSON Response so that we perform some actions with it. Here is how to fetch in a JSONArray the Response returned from an HTTP GET Test:
public void testGetListOfUsers() {
Response response = given()
.accept(JSON)
.when()
.get("/users")
.then()
.statusCode(200)
.contentType(JSON)
.extract()
.response();
String jsonBody = response.getBody().asString();
try {
JSONArray usersArray = new JSONArray(jsonBody);
assertNotNull(usersArray);
assertTrue(usersArray.length() > 0);
} catch (JSONException ex) {
fail(ex.getLocalizedMessage());
}
}
XML Testing with REST assured
XML can be verified in a similar way. Imagine that a POST request to http://localhost:8080/users returns:
<greeting>
<firstName>John</firstName>
<lastName>Doe</lastName>
</greeting>
You can easily perform and verify the firstName with REST assured:
given().
parameters("firstName", "John", "lastName", "Doe").
when().
post("/greetXML").
then().
body("greeting.firstName", equalTo("John")).
If you want to verify both firstName and lastName you may do like this:
given().
parameters("firstName", "John", "lastName", "Doe").
when().
post("/greetXML").
then().
body("greeting.firstName", equalTo("John")).
body("greeting.lastName", equalTo("Doe"));
Testing other HTTP methods
RESTAssured can be tested to verify all HTTP methods (GET/POST/PUT/DELETE). You can attach the HTTP method in the fluent expression as in the following example:
@Test
public void testCar() {
JsonObject car = Json.createObjectBuilder()
.add("make", "Fiat")
.add("model", "500").build();
// Testing HTTP POST
given()
.contentType("application/json")
.body(car.toString())
.when()
.post("/cars")
.then()
.statusCode(201);
// Testing HTTP GET
given()
.when().get("/cars")
.then()
.statusCode(200)
.body(containsString("Fiat"),
containsString("500"));
car = Json.createObjectBuilder()
.add("id", "1")
.add("make", "Opel")
.add("model", "Karl").build();
// Testing HTTP PUT
given()
.contentType("application/json")
.body(obj.toString())
.when()
.put("/cars")
.then()
.statusCode(204);
// Testing HTTP DELETE
given()
.contentType("application/json")
.when()
.delete("/users?id=1")
.then()
.statusCode(204);
}
Compiling REST Assured applications
If you are using Maven to build your project, you need to add the following dependency to your pom.xml:
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
Also, as REST-assured leverages the Hamcrest matchers to perform its assertions, we must include that dependency as well:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
That's all! Enjoy coding with RESTAssured