Users Online
· Members Online: 0
· Total Members: 188
· Newest Member: meenachowdary055
Forum Threads
Latest Articles
Articles Hierarchy
Rest Assured Tutorial for REST API Automation Testing
Deserialize JSON Response using Rest Assured
JSON is an extremely popular format when it comes to APIs. Almost all of the APIs either transfer data in the XML format or JSON format of which JSON is a popular one. Not only through APIs, but the companies also use JSON to transfer data between their own server to UI because of its lightweight and easily readable features. As a professional tester or a developer, it will be rare if you do not come across a JSON file and verify its legibility. To work with them, you should know how to read them through code and make use of automation testing to accomplish your tasks easily. In this article, we'll discuss the same concept used in the body of the REST Response. This technique to read the JSON Response is also termed as to "Deserialize" the JSON Response.
Serialization and Deserialization are programming techniques where we convert Objects to Byte Streams and from Byte Streams back to Objects respectively. We have already discussed this technique in the article Serialization and Deserialization in Java. We will now cover the following topics in this article:
- What is Serializing a JSON?
- What is Deserializing of a JSON Response?
- How to Deserialize JSON Response to Class with Rest Assured?'
- How to Deserialize JSON Response Body based on Response Status?
What is Serializing a JSON?
Serialization, as mentioned above, is a process of converting data objects into a stream of data. The reverse process of serialization (stream to object) is deserialization. Both the processes are platform-independent. This means we can serialize an object on a Windows platform and deserialize it on macOS.
As far as rest assured is concerned, we are aware that the data exchange between client and server takes place in JSON format by REST web service. The stream of data here is JSON data.
For example, if we have the following object:
{tools: [1, 3, 7, 9], api: "QA"}
when the above object is serialized into JSON, the output will look like the one shown below:
{
"tools":[1, 3, 7, 9],
"api":"QA"
}
The above data string can be stored or transferred anywhere. The recipient will then deserialize the data back to its original format ie object.
Java POJO classes are one way we can serialize the objects and use them in Rest Assured. The details of implementation are beyond the scope of this tutorial. Serialization is discussed in our previous tutorial Serialization and Deserialization in Java. While working in the testing industry, we will be more concerned about deserialization. The same is discussed in the next section in detail.
What is Deserializing a JSON Response?
Before going ahead, it is recommended to read the article REST Api testing in Rest-Assured and converse yourself with REST, API testing, REST Assured and other similar concepts.
In REST APIs, the process of deserialization is performed especially for the JSON responses we receive from the API. So, when we say we are deserializing the JSON, this means we convert the JSON format into a type we prefer, most frequently POJO (Plain Old Java Object) classes.
So in this process, we essentially tell our code to use strongly typed strings that are less error-prone instead of JSON strings. Let's go ahead and see practically how to deserialize the JSON responses to class with Rest Assured.
How to Deserialize JSON Response to Class with Rest Assured?
We will continue from our example in Making a POST request using Rest-Assured to implement deserialization of JSON responses. In this article, we have seen that a successful post request sends the following response:
{
"SuccessCode": "OPERATION_SUCCESS",
"Message": "Operation completed successfully"
}
In the POST request example, we have used JSONPath to validate the response body parts. Now we have to convert this response body to a Java class (POJO). In other words, we'll convert the JSON which is a string form to a class form i.e. deserialize JSON.
Note: Deserialization is also called Object Representation of structured data. The structured data here is JSON.
So how do we begin with deserialization?
First and foremost we need to create a class that has all the nodes (or key) of the JSON response. As we are already aware, the Success response has two nodes:
- SuccessCode
- Message
Both these nodes contain String values. The screenshot below shows the part of the response we receive.
So we have to create a class with two string variables that will represent nodes in the JSON. Given below is the class code for the same.
@Test
public class JSONSuccessResponse {
// Note: The name should be exactly as the JSON node name
// Variable SuccessCode will contain value of SuccessCode node
public String SuccessCode;
// Variable Message will contain the value of Message node
public String Message;
}
Now that we have a JSONSuccessResponse class to store all the nodes present in Successful Response, let's understand how to use Rest-Assured to automatically convert JSON Response Body to the instance of the JSONSuccessResponse class.
Converting JSON Response Body to JSONSuccessResponse class
The class io.restassured.response.ResponseBody that represents the response in Rest Assured, has a method called .as(Class<T>). Here, Class<T>
is a generic form of any class of type T which is also referred to as template class. In this case, Class <T>
will be JSONSuccessResponse.
Internally, the "as()" method performs two actions:
- Create an instance of JSONSuccessResponse class.
- Copy the JSON node variables to the respective instance variables of the class. For example, the value of SuccessCode node to the variable SucessCode and value of Message to variable Message.
Given below is the code demonstrating the Response.Body.as(Class<T>
) method.
@Test
public void UserRegistrationSuccessful() {
RestAssured.baseURI ="https://demoqa.com";
RequestSpecification request = RestAssured.given();
JSONObject requestParams = new JSONObject();
requestParams.put("UserName", "test_rest");
requestParams.put("Password", "rest@123");
request.body(requestParams.toJSONString());
Response response = request.post("/Account/v1/User");
ResponseBody body = response.getBody();
// Deserialize the Response body into JSONSuccessResponse
JSONSuccessResponse responseBody = body.as(JSONSuccessResponse.class);
// Use the JSONSuccessResponseclass instance to Assert the values of Response.
Assert.assertEquals("OPERATION_SUCCESS", responseBody.SuccessCode);
Assert.assertEquals("Operation completed successfully", responseBody.Message); }
Once we get the value in responseBody variable, we can validate the response as shown in the code below.
// Use the RegistrationSuccessResponse class instance to Assert the values of
// Response.
Assert.assertEquals("OPERATION_SUCCESS", responseBody.SuccessCode);
Assert.assertEquals("Operation completed successfully", responseBody.Message);
In this way, we can apply assertions to validate the response or even pass this response as input to other tests.
How to Deserialize JSON Response Body based on Response Status?
In the previous section, we discussed how to deserialize the JSON in case of a successful response. But in real-time applications, we can also receive responses that are failures. In such a case, Rest API may return a completely different response body. One such format of failed response may be as shown below:
{
"FaultId": "User already exists",
"fault": "FAULT_USER_ALREADY_EXISTS"
}
If we use the class JSONSuccessResponse to deserialize the above response, it will not work. This is because Rest Assured will not find the nodes SuccessCode and Message in the response body like in the above section. These two variables in the class will have values as null.
The solution to this is to maintain another class that will be used for deserializing the failure response. This class will have the following structure.
public class JSONFailureResponse {
String FaultId;
String fault;
}
But now that we have two classes, one for a successful response and another for failure, how can we handle both these in an application?
We can do this using the HTTP Status Code returned by the server. Rest API in this series returns Status Code = 201 in case of success and 200 in case of failure.
So by making use of the status code we can deserialize the response into appropriate POJO classes depending on success or failure. Below given code is an updated version of the above code and it takes care of success as well as failure response.
@Test
public void UserRegistrationSuccessful() {
RestAssured.baseURI ="https://demoqa.com";
RequestSpecification request = RestAssured.given();
JSONObject requestParams = new JSONObject();
requestParams.put("UserName", "test_rest");
requestParams.put("Password", "rest@123");
request.body(requestParams.toJSONString());
Response response = request.post("/Account/v1/User");
ResponseBody body = response.getBody();
System.out.println(response.body().asString());
if(response.statusCode() == 200) {
// Deserialize the Response body into JSONFailureResponse
JSONFailureResponse responseBody = body.as(JSONFailureResponse.class);
// Use the JSONFailureResponse class instance to Assert the values of Response.
Assert.assertEquals("User already exists", responseBody.FaultId);
Assert.assertEquals("FAULT_USER_ALREADY_EXISTS", responseBody.fault);
} else if (response.statusCode() == 201) {
// Deserialize the Response body into JSONSuccessResponse
JSONSuccessResponse responseBody = body.as(JSONSuccessResponse.class);
// Use the JSONSuccessResponse class instance to Assert the values of response.
Assert.assertEquals("OPERATION_SUCCESS", responseBody.SuccessCode);
Assert.assertEquals("Operation completed successfully", responseBody.Message);
}
}
In the above code, we deserialize the response to JSONSuccessResponse or JSONFailureResponse class depending on whether the Status code is Success or Failure.
Note: Another way to deserialize multiple responses is by using the inheritance chain which readers can implement as an exercise.
Key TakeAways
In this article, we have discussed the deserialization of JSON responses into a POJO class.
- Deserialization is the process of converting JSON responses into classes. By doing this we can convert JSON strings into strongly types strings that are less error-prone.
- For deserializing the responses, we create a separate class that has the same variables that are present in the JSON response like StatusCode and Message.
- In the code, we can use this class object to read the JSON response as shown in the example above.
- Deserialization of multiple responses like success and failure depends on the status code. For this, we need two POJO classes one each for success and failure. Depending on the value of the Status code we can call instances of the appropriate class and deserialize the response.
In our next article, we will discuss authentication and authorization in Rest.