In this REST Assured tutorial, you will learn how easy it is to test and validate RESTful APIs. REST Assured provides excellent HTTP support, explicit verbs, and actions. We will use REST Assured in this tutorial and the Hamcrest library to perform assertions.
REST Assured Maven Dependencies
Before laying down examples for this library, we need to make a Maven project with the dependencies below. To learn how to create a simple Web Services Project with Maven, check this tutorial Create a Simple Web Service Project with Spring Boot
<dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>3.0.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-all</artifactId> <version>1.3</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
The first dependency is for REST Assured, followed by the Hamcrest dependency as we will also be using that library for assertions. The last dependency is for JUnit.
Find the latest dependencies for REST Assured and Hamcrest on Maven central. We can run a simple maven command to see the dependency tree of the project, which will show all dependencies which are present in the project:
mvn dependency:tree
Testing with REST Assured Example
To make a simple example, we will take a REST API which returns user profile data to us, which is of the form:
{ "username" : "sergey", "password" : "qwerty", "email" : "[email protected]", "firstName" : "Sergey", "lastName" : "Kargopolov", "inviteCode" : ["1234", "4567"] }
Let’s say that this is the JSON response we get when we hit the API:
http://localhost:8080/users/sergey
Check if JSON Key Has a Value
When we write a test case for this API, we will be able to test the content of JSON representation:
import org.junit.Test; import static io.restassured.RestAssured.get; import static org.hamcrest.core.IsEqual.equalTo; public class UserTest { @Test public void givenUrl_whenSuccessAndJsonHasUsername_thenCorrect() { get("/users/sergey").then().statusCode(200).assertThat() .body("username", equalTo("sergey")); } }
We first made a GET request to the user and verified if its body actually had a ‘username’ key in the JSON whose value is ‘sergey’. That was easy. But what if you wanted to do a more complex assertion of comparing the ‘inviteCode’ array? Let’s try another example.
Check If JSON Array has a Value
We can check if JSON Array contains one of the expected values this way:
import org.junit.Test; import static io.restassured.RestAssured.get; import static org.hamcrest.CoreMatchers.hasItems; public class UserTest { @Test public void givenUrl_whenSuccessAndJsonHasArrayItem_thenCorrect() { get("/users/sergey").then().statusCode(200).assertThat() .body("inviteCode", hasItems("1234")); } }
JSON Root Data Validation
Suppose we have an array which comprises primitive values rather than any JSON key-value objects, like:
["Sergey", "Java", "Android", "Firebase"]
This is an anonymous JSON root, as it has no key-value pair in JSON data. We can still run validations on this data using the $ symbol. If this data is reachable at endpoint /data, the test will look like this:
@Test public void whenAnonymous_thenCorrect() { get("/data").then().statusCode(200).assertThat() .body("$", hasItems("Sergey", "Android")); }
Or a GET statement without any identifier will work equivalently well too:
get("/data").then().statusCode(200).assertThat() .body("", hasItems("Sergey", "Android"));
Testing Floats and Doubles with REST Assured
When writing the test cases and using assertions using the REST Assured library for HTTP calls, we need to note that the floating point numbers in the JSON data we get are converted to the primitive type float, and this mapping is not interchangeable with double as is the case for many other scenarios in Java.
So, if we have some JSON response data like:
{ "username" : "sergey", "password" : "qwedsa", "email" : "[email protected]", "firstName" : "Sergey", "lastName" : "Kargopolov", "credits" : 12.9 }
When we try to test this service against an endpoint, suppose /credits, as:
@Test public void whenTreatedDouble_thenFail() { get("/credits").then().statusCode(200).assertThat() .body("credits", equalTo(12.9)); }
The mentioned test case will fail as the number 12.9 will be treated as a Double and not as a Floating point number. This can be corrected with the following representation:
@Test public void whenTreatedDouble_thenCorrect() { get("/credits").then().statusCode(200).assertThat() .body("credits", equalTo(12.9F)); }
Explicitly Specifying Request Method
Although we are free to use the static methods we’ve been using in all the above test cases, we can use a general method and pass in the request method name as String which we want to use for the request.
Let’s have a look at this example:
@Test public void whenMethodGet_thenOK(){ when().request("GET", "/users/sergey").then().statusCode(200); }
This works exactly the same way for other HTTP Methods:
@Test public void whenMethodPost_thenOK(){ when().request("POST", "/users/sergey").then().statusCode(200); } @Test public void whenMethodOptions_thenOK(){ when().request("OPTIONS", "/users/sergey").then().statusCode(200); }
REST Assured BaseURI
In many cases, most of the test cases we write for the Controller layer uses the same Base URI for the APIs. Parameters like these can be set in the config annotated method for the RestAssured class setup method:
@Before public void setup() { RestAssured.baseURI = "http://localhost"; RestAssured.port = 8080; }
or
@Before public void setup() { RestAssured.baseURI = "http://localhost:8080"; }
Many other properties can be set in the config method marked with @Before annotations, which ensures that this method is executed before any test cases are executed.
Measuring Response Time with REST Assured
One of the most useful features I find of the RestAssured library is that it provides a very easy way to measure response time for an API we use. This can even be used in performance-related testing for the APIs, which is made much easier with this simple code. Let’s look at an example:
@Test public void whenMeasureResponseTime_thenCorrect() { Response data = RestAssured.get("/users/sergey"); long timeInMillis = data.time(); long timeInSec = data.timeIn(TimeUnit.SECONDS); assertEquals(timeInSec, timeInMillis/1000); }
With this simple call for response data and direct methods provided to measure the response time, we can perform many cases in which the performance of an API can be audited.
Logging Request Details
The request calls made with the RestAssured library can be easily printed for debugging purposes and even to explore properties in a request object. Here is an example:
@Test public void whenLogRequest_thenCorrect() { given().log().all() .when().get("/users/sergey") .then().statusCode(200); }
This request will produce logs on the console something like:
Request method: GET Request URI: http://localhost:8080/users/sergey Proxy: <none> Request params: <none> Query params: <none> Form params: <none> Path params: <none> Multiparts: <none> Headers: Accept=*/* Cookies: <none> Body: <none>
I hope this short tutorial was helpful to you. I will publish a few more tutorials on this topic, so stay tuned.
Conclusion
In conclusion, REST Assured is a powerful testing framework for RESTful APIs in Java, allowing developers to write expressive and comprehensive tests. By utilizing REST Assured, developers can verify the behavior and correctness of their APIs with ease.
Looking to master testing RESTful web services? Visit the Testing Java Code page and explore our comprehensive tutorial on testing RESTful APIs with REST Assured. Gain valuable insights and techniques to effectively verify the behavior of your web services.
If you like learning new material by following step-by-step video tutorials, check out the below list of video courses. One of them might help you speed up your learning progress.