RESTAssured tutorial

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