REST Assured is a Java library that offers programmers a domain-specific language (DSL) to write maintainable, robust tests for RESTful APIs. It is widely used to test web applications based on JSON and XML. Additionally, it supports all methods, including GET, DELETE, PUT, POST, and PATCH.
REST is an acronym for “representational state transfer.” It’s a design pattern or architectural style for APIs. A RESTful web application reveals information about itself as resource information.
JSON stands for “JavaScript Object Notation” which is a lightweight , language independent and self describing format in text for data storing and interchange. JSON is easy to read, write and create for humans which makes it famous over XML.
JSON was derived from JavaScript but now it is supported by many languages. A file containing JSON is saved using “.json” extension.
When we want to create a new resource or say want to add a new student details in to a student database, we need to send a POST request with a payload to API end point. This payload can be a JSON format. So , JSON is majorly used to exchange data between Web Server and Client.
An example JSON is below:-
{
“firstName”:”Phani”,
“lastName”:”Nagula”,
“age”: 45,
“salary”: 00.01
}
As you see above, JSON stores data as a key-value pair. Key is left side and value is right side and a semi colon is used to separate both. One key-value pair is separated with another key-value pair using comma (,).
A key is always a string and a string must be enclosed in double quotes. A value can be a string, number ( With decimal and without decimal ), a Boolean ( true and false) , an object , an array or a null.
JSON can be found in two formats :- JSON Object and JSON Array.
A JSON Object is an unordered data structure which starts with opening braces ( ‘{‘) and ends with a closing braces (‘}’). A JSON Array is a ordered collection which starts with opening bracket ( ‘[‘) and ends with a closing bracket(‘]’). A JSON array consists of values separated by comma. A JSON array can be hold multiple JSON Objects as well.
RESTful web services use the HTTP protocol to communicate between the client and the server.
The REST architecture treats any content as a resource. This content includes HTML pages, text files, images, videos, or dynamic business information. A REST Server gives users access to these resources and modifies them, and URIs or global IDs identify each resource.
In the context of object-oriented programming languages, method chaining is an often-used syntax for invoking any number of method calls. Each method returns an object, so multiple calls can be chained together in a single line. This characteristic means that variables aren’t needed to hold interim results.
Because REST Assured can customize reports, Postman can’t do this. Additionally, since REST Assured is a Java client, you can reuse code, which Postman doesn’t allow. Finally, REST Assured has no restrictions on data file submission for collections, whereas Postman is limited to one data file.
Request specification in REST Assured is used to group common request specs and change them into a single object. This interface has the means to define the base URL, headers, base path, and other parameters. You must use the given() function of the REST Assured class to obtain a reference for the Request specification.
A RequestSpecification with some specifications can be created as below:-
RequestSpecification requestSpecification = RestAssured.given();
requestSpecification.baseUri(“https://hireqa.co.in”)
requestSpecification.basePath(“/register”);
Or instead of calling RequestSpecification reference multiple times, we can use the builder pattern as below:-
RequestSpecification requestSpecification = RestAssured.given()
.baseUri(“https://restful-booker.herokuapp.com”)
.basePath(“/booking”);
We can add a RequestSpecification to a request in multiple ways as shown below:-
RestAssured.given(requestSpecification)
OR
RestAssured.given().spec(requestSpecification)
import org.testng.annotations.Test;
import io.restassured.RestAssured;
import io.restassured.http.Method;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
public class EmployeesTest {
@Test
public void GetAllEmoloyees()
{
// base URL to call
RestAssured.baseURI = "http://localhost:8080/employees/get";
//Provide HTTP method type - GET, and URL to get all employees
//This will give respose
Response employeesResponse = RestAssured.given().request(Method.GET, "/all");
// Print the response in string format
System.out.println(employeesResponse.getBody().asString());
}
}
Use a blacklist to prevent sensitive data from appearing in the log. Here’s how:
Set headers = new HashSet();
headers.add("X-REGION");
headers.add("content-type");
given().baseUri("http://localhost:8080").header("X-REGION", "NAM")
// blacklist headers
.config(config.logConfig(LogConfig.logConfig().blacklistHeaders(headers)))
// blacklist multiple headers
.config(config().logConfig(LogConfig.logConfig().blacklistHeader("Accept","set-cookie")))
.log().all()
.when()
.get("/employees")
.then()
.assertThat()
.statusCode(200);
A JsonPath (io.restassured.path.json.JsonPath) is an easy way to get values from an Object document without resorting to XPath. It conforms to the Groovy GPath syntax when it retrieves an object from a document. Consider it a JSON-specific version of XPath. Here’s an example:
{
"company":{
"employee":[
{
"id":1,
"name":"User1",
"role":"Admin"
},
{
"id":2,
"name":"User2",
"role":"User"
},
{
"id":3,
"name":"User3",
"role":"User"
}
]
}
}
Response employeesResponse = RestAssured.given().request(Method.GET, "/all");
JsonPath jsonPathObj = employeesResponse.jsonPath();
//get a list of all employees id:
List employeeIds = jsonPathObj.get("company.employee.id");
//get the first employee name:
String empName = jsonPathObj.get("company.employee[0].name");
If the test validation fails, log().ifValidationFails() will log everything in a request and response.
@Test
public void testIfValidationFails() {
given().
baseUri("http://localhost:8080").
header("X-REGION", "NAM").
log().ifValidationFails().
when().
get("/employees").
then().
log().ifValidationFails().
assertThat().
statusCode(200);
}
Response employeesResponse = RestAssured.given().request(Method.GET, “/all”);
JsonPath jsonPathObj = employeesResponse.jsonPath();
//get all employees id between 15 and 300
List employees = jsonPathObj.get(“company.employee
.findAll { employee -> employee.id >= 15 && employee.id <= 300 }");
Static import is a Java programming language function that lets members (e.g., fields and methods) scoped as public static within their container class to be employed in Java code without mentioning the field’s defined class.
import static io.restassured.RestAssured.*;
public class EmpControllerTest {
@Test
public void testGetEmployees() {
// with static import
given();
// without static import
/**
* import io.restassured.RestAssured;
* RestAssured.given();
*/
}
}
Serialization is defined as the process of changing an object’s state into a byte stream. On the other hand, deserialization is the process of recreating the Java object in memory using the byte stream. This approach keeps the object alive.
RequestSpecBuilder is a class in Rest Assured, which contains methods to set cookies, headers, multipart details, body, authentication, form parameters, query parameters, path parameters, base path, base URI, proxy, etc. These all are required to construct a Requestspecification. After adding all required details, we need to use “build()” method of RequestSpecBuilder class to get a RequestSpecification reference.
// Creating an object of RequestSpecBuilder
RequestSpecBuilder reqBuilder = new RequestSpecBuilder();
// Setting Base URI
reqBuilder.setBaseUri(“https://restful-booker.herokuapp.com”);
// Setting Base Path
reqBuilder.setBasePath(“/booking”);
// Getting RequestSpecification reference using builder() method
RequestSpecification reqSpec = reqBuilder.build();
// We can directly call http verbs on RequestSpecification
Response res1= reqSpec.get();
System.out.println(res1.asString());
or
// We can also pass RequestSpecification reference variable in overloaded given() method
Response res2 = RestAssured.given(reqSpec).get();
System.out.println(res2.asString());
or
// We can also pass RequestSpecification using spec() method
Response res3 = RestAssured.given().spec(reqSpec).get();
System.out.println(res3.asString());
RequestSpecification req= RestAssured.given()
.accept(ContentType.JSON)
.auth().preemptive().basic("username", "password")
.header("headername", "headervalue")
.param("paramname", "paramvalue")
.cookie("cookieName", "value");
Rest Assured allows you to arrange your test script in BDD style using Given, When and Then.
Prerequisites to perform Request:- GIVEN
E.g.- Setting the Base URI, Base Path, Content Type , Request body (Payload) , cookies, headers , authentication , params etc.
Performing Request :- WHEN
E.g:- Which HTTP request to hit i.e. HTTP verbs – GET, POST etc
Verification and extracting response post hitting :- THEN
E.g. Verify status code, response data, log, extracting data etc.
// Given
RestAssured.given()
.baseUri("https://hireqa.co.in")
// When
.when()
.get("/register")
// Then
.then()
.statusCode(200)
.statusLine("HTTP/1.1 200 OK")
// To verify register count
.body("registerid", Matchers.hasSize(10))
// To verify booking id at index 3
.body("registerid[3]", Matchers.equalTo(1));
// There is no need to add escape character manually. Just paste string within double
// quotes. It will automatically add escape sequence as required.
String jsonString = "{\"username\" : \"admin\",\"password\" : \"password123\"}";
//GIVEN
RestAssured
.given()
.baseUri("https://hireqa.co.in/register")
.contentType(ContentType.JSON)
.body(jsonString)
// WHEN
.when()
.post()
// THEN
.then()
.assertThat()
.statusCode(200)
.body("token", Matchers.notNullValue())
.body("token.length()", Matchers.is(15))
.body("token", Matchers.matchesRegex("^[a-z0-9]+$"));
//GIVEN
RestAssured
.given()
.baseUri("https://hireqa.co.in/register/1")
.cookie("token", "12345678")
.contentType(ContentType.JSON)
.body(jsonString)
// WHEN
.when()
.put()
// THEN
.then()
.assertThat()
.statusCode(200)
.body("firstname", Matchers.equalTo("Phani"))
.body("lastname", Matchers.equalTo("Nagula"));
RestAssured
.given()
.baseUri("https://hireqa.co.in/register/1")
.cookie("token", "12345678")
.contentType(ContentType.JSON)
.body(jsonString)
// WHEN
.when()
.patch()
// THEN
.then()
.assertThat()
.statusCode(200)
.body("firstname", Matchers.equalTo("Phani"))
.body("lastname", Matchers.equalTo("Nagula"));
//GIVEN
RestAssured
.given()
.baseUri("https://hireqa.co.in/register/1")
.cookie("token", "12345678")
// WHEN
.when()
.delete()
// THEN
.then()
.assertThat()
.statusCode(204);
// Verifying booking is deleted
// Given
RestAssured
.given()
.baseUri("https://hireqa.co.in/register/1")
// When
.when()
.get()
// Then
.then()
.statusCode(404);
Rest Assured provides below methods to get a response as:-
- As byte array :- asByteArray()
- As input stream :- asInputStream()
- As string :- asString()
All the above methods output can be used to write into a JSON file.
// Create a request specification
RequestSpecification request = RestAssured.given();
// ContentType is an ENUM.
.contentType(ContentType.JSON)
// Adding URI
.baseUri("https://hireqa.co.in/auth")
// Adding body as string
.body(jsonString)
Response response = request .when().post();
// Getting response as a string and writing in to a file
String responseAsString = response.asString();
// Converting in to byte array before writing
byte[] responseAsStringByte = responseAsString.getBytes();
// Creating a target file
File targetFileForString = new File("D:/RestAssured/targetFileForString.json");
// Writing into files
Files.write(responseAsStringByte, targetFileForString);
// Getting response as input stream and writing in to a file
InputStream responseAsInputStream = response.asInputStream();
// Creating a byte array with number of bytes of input stream
byte[] responseAsInputStreamByte = new byte[responseAsInputStream.available()];
// Reads number of bytes from the input stream and stores them into the byte
// array responseAsInputStreamByte.
responseAsInputStream.read(responseAsInputStreamByte);
// Creating a target file
File targetFileForInputStream = new File(D:/RestAssured/targetFileForInputStream.json");
// Writing into files
Files.write(responseAsInputStreamByte, targetFileForInputStream);
// Directly getting a byte array
byte[] responseAsByteArray = response.asByteArray();
// Creating a target file
File targetFileForByteArray = new File("D:/RestAssured/targetFileForByteArray.json");
// Writing into files
Files.write(responseAsByteArray, targetFileForByteArray);
// Creating request specification using given()
RequestSpecification request1= RestAssured.given();
// Setting Base URI
request1.baseUri(“https://hireqa.co.in”);
// Setting Base Path
request1.basePath(“/booking”);
// We can directly call http verbs on RequestSpecification
Response res1= request1.get();
System.out.println(res1.asString());
// We can also pass RequestSpecification reference variable in overloaded given() method
Response res2 = RestAssured.given(request1).get();
System.out.println(res2.asString());
// We can also pass RequestSpecification using spec() method
Response res3 = RestAssured.given().spec(request1).get();
System.out.println(res3.asString());
To query or retrieve details from RequestSpecification, Rest Assured provides a class named SpecificationQuerier. This class has a static method called query(RequestSpecification specification) which returns reference of QueryableRequestSpecification interface. This interface has methods to retrieve request details such as getBasePath(), getBody() etc.
// Creating request specification using given()
RequestSpecification request1= RestAssured.given();
// Setting Base URI
request1.baseUri("https://hireqa.co.in")
// Setting Base Path
.basePath("/register")
.body(JsonBody)
.header("header1", "headerValue1")
.header("header2", "headerValue2");
// Querying RequestSpecification
// Use query() method of SpecificationQuerier class to query
QueryableRequestSpecification queryRequest = SpecificationQuerier.query(request1);
// get base URI
String retrieveURI = queryRequest.getBaseUri();
System.out.println("Base URI is : "+retrieveURI);
// get base Path
String retrievePath = queryRequest.getBasePath();
System.out.println("Base PATH is : "+retrievePath);
// get Body
String retrieveBody = queryRequest.getBody();
System.out.println("Body is : "+retrieveBody);
// Get Headers
Headers allHeaders = queryRequest.getHeaders();
System.out.println("Printing all headers: ");
for(Header h : allHeaders)
{
System.out.println("Header name : "+ h.getName()+" Header value is : "+h.getValue());
}
Suppose you have a request payload (JSON or XML) in a file and you required to directly send that file as a payload to request in stead of reading it first and then passing. Sending file as a payload directly is a good idea when you have static payloads or minimal modification.
“body()” method of RequestSpecification interface is a overloaded method to allow you to pass payload in different ways. We will use body() method which accepts “File” as argument.
// Creating a File instance
File jsonFile = new File("D:/RestAssured/jsonPayload.json");
//GIVEN
RestAssured
.given()
.baseUri("https://hireqa.co.in")
.contentType(ContentType.JSON)
.body(jsonFile)
// WHEN
.when()
.post()
// THEN
.then()
.assertThat()
.statusCode(200)
.body("token", Matchers.notNullValue())
.body("token.length()", Matchers.is(15))
.body("token", Matchers.matchesRegex("^[a-z0-9]+$"));
When a request is sent to a server, it responds with a response. The amount of time taken between sending a request to server and retrieving a response back form a server is called Response Time. An API must be faster. As a part of API testing, we must check the response time as well.
- If you just want to retrieve response time in milliseconds or other time units, you need to use time(), getTime(), timeIn(TimeUnit timeunit), getTimeIn( TimeUnit timeunit ) from Response interface. Response interface inherits these methods from ResponseOptions. You can not use Matchers in above methods.
- If you want to use Matchers i.e. assertion like response time is greater than a specific value, you need to use overloaded time() methods from ValidatableResponse which inherits time() method from ValidatableResponseOptions interface.
Interface ResponseOptions contains four methods :-
- getTime() – The response time in milliseconds (or -1 if no response time could be measured)
- getTimeIn(TimeUnit timeunit) – The response time in the given time unit (or -1 if no response time could be measured)
- time() – The response time in milliseconds (or -1 if no response time could be measured)
- timeIn( TimeUnit timeunit ) – The response time in the given time unit (or -1 if no response time could be measured)
// Create a request specification
RequestSpecification request= RestAssured.given();
// Setting content type to specify format in which request payload will be sent.
// ContentType is an ENUM.
request.contentType(ContentType.JSON);
//Adding URI
request.baseUri("https://hireqa.co.in/register");
// Adding body as string
request.body(jsonString);
// Calling POST method on URI. After hitting we get Response
Response response = request.post();
// By default response time is given in milliseconds
long responseTime1 = response.getTime();
System.out.println("Response time in ms using getTime():"+responseTime1);
// we can get response time in other format as well
long responseTimeInSeconds = response.getTimeIn(TimeUnit.SECONDS);
System.out.println("Response time in seconds using getTimeIn():"+responseTimeInSeconds);
// Similar methods
long responseTime2 = response.time();
System.out.println("Response time in ms using time():"+responseTime2);
long responseTimeInSeconds1 = response.timeIn(TimeUnit.SECONDS);
System.out.println("Response time in seconds using timeIn():"+responseTimeInSecon
This ValidatableResponseOptions interface has overloaded time() methods which accepts Matcher.
- time(Matcher matcher) – Validate that the response time (in milliseconds) matches the supplied matcher.
- time(Matcher macther, TimeUnit timeunit) – Validate that the response time matches the supplied matcher and time unit.
// Calling POST method on URI. After hitting we get Response
Response response = request.post();
// Getting ValidatableResponse type
ValidatableResponse valRes = response.then();
// Asserting response time is less than 2000 milliseconds
// L just represent long. It is in millisecond by default.
valRes.time(Matchers.lessThan(2000L));
// Asserting response time is greater than 2000 milliseconds
valRes.time(Matchers.greaterThan(2000L));
// Asserting response time in between some values
valRes.time(Matchers.both(Matchers.greaterThanOrEqualTo(2000L)).and(Matchers.lessThanOrEqualTo(1000L)));
// If we want to assert in different time units
valRes.time(Matchers.lessThan(2L), TimeUnit.SECONDS);
We can create a JSON Object using a Map in Java. You must note here that I am using the word “JSON Object”. A JSON Object is a key-value pair and can be easily created using a Java Map. A Map in Java also represents a collection of key-value pairs.
{
“username” : “Phani”,
“lastname” : “Nagula”
}
Map mapPayload = new HashMap();
mapPayload .put("username", "Phani");
mapPayload .put("lastname", "Nagula");
RestAssured
.given()
.baseUri("https://hireqa.co.in/register")
.contentType(ContentType.JSON)
.body(mapPayload )
.log()
.all()
// WHEN
.when()
.post()
// THEN
.then()
.assertThat()
.statusCode(200)
.log()
.all();
Example Json Array Object:
[
{
"firstname" : "Phani",
"lastname" : "Nagula"
}
{
"firstname" : "Swapna",
"lastname" : "Nalla"
}
]
====================================
Map objectOne = new HashMap();
objectOne.put("firstname","Phani");
objectOne.put("lastname", "Nagula");
Map objectTwo = new HashMap();
objectOne.put("firstname","Swapna");
objectOne.put("lastname", "Nalla");
// Creating JSON array to add both JSON objects
List<Map> jsonArrayPayload = new ArrayList();
jsonArrayPayload.add(objectOne);
jsonArrayPayload.add(objectTwo);
//GIVEN
RestAssured
.given()
.baseUri("https://hireqa.co.in/register")
.contentType(ContentType.JSON)
.body(jsonArrayPayload)
.log()
.all()
// WHEN
.when()
.post()
// THEN
.then()
.assertThat()
// Asserting status code as 500 as it does not accept json array payload
.statusCode(500)
.log()
.all();
Jackson API is a high performance JSON processor for Java. We can perform serialization, deserialization , reading a JSON file, writing a JSON file and a lot more things using Jackson API.
To use Jackson API, we need to add it in java project build path. You can add using Maven or download a jar file with transitive jars.
Maven dependency
com.fasterxml.jackson.core
jackson-databind
2.14.1
jackosn-databind dependency will automatically download transitive dependencies of same version i.e. jackson-annotations and jackson-core as well.
We will use Class ObjectMapper to create a JSON Object or ObjectNode.
- To create a JSON Object using Jackson, we need to use createObjectNode() method of ObjectMapper class which returns an ObjectNode class instance.
- ObjectNode class has overloaded methods put(String fieldName, T fieldValue ) which takes field Name as String and values of different primitive and wrapper class types like String, Boolean etc.
- All field names should be unique. If you pass duplicate field name, it will not throw any error but override field values by latest. It is similar to put() method of Map in Java.
To get the created JSON Object as string, use writeValueAsString() provided by ObjectMapper class. If you want in proper JSON format, use writerWithDefaultPrettyPrinter() method for formatting.
Example Code for Json Object:
{
"firstname" : "Phani",
"lastname" : "Nagula"
}
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeDetails = objectMapper.createObjectNode();
employeeDetails.put("firstname", "Phani");
employeeDetails.put("lastname", "Nagula");
// To print created json object
String createdPlainJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeeDetails);
System.out.println("Created plain JSON Object is : \n"+ createdPlainJsonObject);
Example Code for Nested Json Object:
{
"employee" : {
"firstname" : "Phani",
"lastname" : "Nagula"
}
}
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeInfo = objectMapper.createObjectNode();
ObjectNode employeeDetails = objectMapper.createObjectNode();
employeeDetails.put("firstname", "Phani");
employeeDetails.put("lastname", "Nagula");
employeeInfo.set("employee", "employeeDetails");
// To print created json object
String createdPlainJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeeInfo);
System.out.println("Created plain JSON Object is : \n"+ createdPlainJsonObject);
To create a nested JSON Object or put another JSON Object as field value, we can not use put(String fieldName, JsonNode fieldValue) as it is deprecated. We use set(String fieldName, JsonNode fieldValue) or replace(String fieldName, JsonNode fieldValue)
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeInfo = objectMapper.createObjectNode();
ObjectNode employeeDetails = objectMapper.createObjectNode();
employeeDetails.put("firstname", "Phani");
employeeDetails.put("lastname", "Nagula");
employeeInfo.set("employee", "employeeDetails");
// To print created json object
String createdPlainJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeeInfo);
System.out.println("Created plain JSON Object is : \n"+ createdPlainJsonObject);
To retrieve a field value we need to use get(String fieldName). If passed field name does not have a value or if there is no field with such name, null is returned. It returns a JsonNode. To get value in actual data types we need to use respective methods like asText() to get value as String or asBoolean() to get value as boolean. Be careful when field value is another ObjectNode.
//defining a JSON string
String s="{\"name\":\"Phani\",\"Salary\":50000.0}";
Object obj=JSONValue.parse(s);
//creating an object of JSONObject class and casting the object into JSONObject type
JSONObject jsonObject = (JSONObject) obj;
//getting values form the JSONObject and casting that values into corresponding types
String name = jsonObject.get("name").asText();
double salary = jsonObject.get("Salary").asDouble();
//printing the values
System.out.println("Name: "+name);
System.out.println("Salary: "+salary);
To retrieve all field names from a ObjectNode, we need to use fieldNames() methods which returns an Iterator. To get count of fields in an ObjectNode, we can use size() method.
Example Code for Json Object:
{
"firstname" : "Phani",
"lastname" : "Nagula"
}
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeInfo = objectMapper.createObjectNode();
employeeInfo.put("firstname", "Phani");
employeeInfo.put("lastname", "Nagula");
// To get all field names
System.out.println("Count of fields in ObjectNode : "+ employeeInfo.size());
Iterator allFieldNames = employeeInfo.fieldNames();
System.out.println("Fields are : ");
while(allFieldNames.hasNext())
{
System.out.println(allFieldNames.next());
}
To retrieve all field values from an ObjectNode, use elements() method which returns an Iterator of JsonNode.
Example Code for Json Object:
{
"firstname" : "Phani",
"lastname" : "Nagula"
}
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeInfo = objectMapper.createObjectNode();
employeeInfo.put("firstname", "Phani");
employeeInfo.put("lastname", "Nagula");
// To get all field values
Iterator allFieldValues = employeeInfo.elements();
System.out.println("Fields values are : ");
while(allFieldValues.hasNext())
{
System.out.println(allFieldValues.next());
}
We can use fields() method to get all fields (with both names and values) of a JSON Object. It returns an Iterator<Entry>.
Example Code for Json Object:
{
"firstname" : "Phani",
"lastname" : "Nagula"
}
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeInfo = objectMapper.createObjectNode();
employeeInfo.put("firstname", "Phani");
employeeInfo.put("lastname", "Nagula");
// To get all key-value pair
Iterator<Entry> allFieldsAndValues = employeeInfo.fields();
System.out.println("All fields and their values are : ");
while(allFieldsAndValues.hasNext())
{
Entry node = allFieldsAndValues.next();
System.out.println("Key is : "+node.getKey()+" and its value is : "+node.getValue());
}
Use remove(String fieldName) method to remove a field from ObjectNode. It will return value of the field, if such field existed; null if not.
Example Code for Json Object:
{
"firstname" : "Phani",
"lastname" : "Nagula"
}
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeInfo = objectMapper.createObjectNode();
employeeInfo.put("firstname", "Phani");
employeeInfo.put("lastname", "Nagula");
// To remove a field
String removedFieldValue = employeeInfo.remove("firstname").asText();
System.out.println("Value of Removed field is " + removedFieldValue);
String removedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeeInfo);
System.out.println("After removing field , JSON Object is : \n"+ removedJsonObject);
We need to use put() method to update a field value if fieldValue is not another ObjectNode. If fieldValue is an ObjectNode use set() or replace() method.
// To replace a field value, use put() method for non ObjectNode type and replace() or set() for ObjectNode
employeeInfo.put("firstname", "Swapna");
employeeInfo.put("firstname", "Nalla");
String updatedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeeInfo);
System.out.println("After updating field , JSON Object is : \n"+ updatedJsonObject);
- Whether it will be serialized to JSON or XML that depends upon what we pass as Content-Type. If we pass Content-Type as application/json then Rest Assured will serialize the Object to JSON. To serialize to JSON , Rest Assured will look for which JSON parser is available in class path.
- First it looks for Jackson. If Jackson is not found it looks for GSON. If both are not found then an exception IllegalArgumentException stating “Cannot serialize because no JSON or XML serializer found in classpath.” will be thrown.
- If we pass Content-Type as “application/xml” then Rest Assured will serialize Object in to XML and for that it looks for JAXB library in class path of project. If it is not found then an exception IllegalArgumentException stating “Cannot serialize because no JSON or XML serializer found in classpath.” will be thrown.
Note :- This works for the POST and PUT methods only.
To create a JSON Object we used createObjectNode() method of ObjectMapper class. Similarly to create JSON Array we use createArrayNode() method of ObjectMapper class. createArrayNode() will return reference of ArrayNode class.
Example Json Array Object:
[
{
"employeeDetails" : {
"firstname" : "Phani",
"lastname" : "Nagula"
}
}
]
ObjectMapper objectMapper = new ObjectMapper();
// Create an array which will hold two JSON objects
ArrayNode parentArray = objectMapper.createArrayNode();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode employeeInfo = objectMapper.createObjectNode()
employeeInfo.put("firstname", "Phani");
employeeInfo.put("lastname", "Nagula");
employeeInfo.set("employeeDetails", employeeDetails);
parentArray .add(employeeInfo);
To print created JSON array as string with proper format:
String jsonArrayAsString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(parentArray);
System.out.println("Created Json Array is : ");
System.out.println(jsonArrayAsString);
Retrieving JSON Object from JSON array using index
// To get json array element using index
JsonNode firstElement = parentArray.get(0);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(firstElement));
Get size of JSON Array
size() method can be used to get size of JSON Array.
int sizeOfArray = parentArray.size();
System.out.println("Size of array is "+sizeOfArray);
Remove a JSON Object from JSON Array
// To remove an element from array
parentArray.remove(0);
System.out.println("After removing first element from array : "+ objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(parentArray));
Empty JSON Array
// To empty JSON Array
parentArray.removeAll();
System.out.println("After removing all elements from array : "+ objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(parentArray));
POJO stands for Plain Old Java Object and it is an ordinary Java objects not a special kind of. The term POJO was coined by Martin Fowler, Rebecca Parsons and Josh MacKenzie in September 2000 when they were talking on many benefits of encoding business logic into regular java objects rather than using Entity Beans or JavaBeans.
From the full form of OOPs , we can understand that it is a programming approach which is oriented around something called “Object” and an Object can contain data (Member variables ) and mechanism (member functions) to manipulate on these data.
A POJO class can follow some rules for better usability. These rules are :-
- Each variable should be declared as private just to restrict direct access.
- Each variable which needs to be accessed outside class may have a getter or a setter or both methods. If value of a field is stored after some calculations then we must not have any setter method for that.
- It Should have a default public constructor.
- Can override toString(), hashcode and equals() methods.
- Can contain business logic as required.
There are some restrictions imposed by Java language specifications on POJO. A POJO should not :-
- Extend prespecified classes
- Implement prespecified interfaces
- Contain prespecified annotations
Advantages of POJO :-
- Increases readability
- Provides type checks
- Can be serialized and deserialized
- Can be used anywhere with any framework
- Data Manipulation is easier. We can have logic before setting and getting a value.
- Builder pattern can be used with POJO.
- Frequently used to create payloads for API.
- Reusability
Example Json Object:
{
“firstName”: “Phani”,
“lastName”: “Nagula”,
“gender”: “Male”,
“age”: 45,
“salary”: 50000,
“married”: true
}
public class Employee {
// private variables or data members of pojo class
private String firstName;
private String lastName;
private String gender;
private int age;
private double salary;
private boolean married;
// Getter and setter methods
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public boolean getMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
}
We have created a POJO class of employee JSON.
Using above POJO class you can create any number of custom Employee objects and each object can be converted in to a JSON Object and Each JSON object can be parsed in to Employee POJO. If you have an API which requires dynamic payload of Employee then you can easily create as many as required employee payloads with different data in stead of creating hard coded JSON objects. In simple words POJO gives you flexibility of creating and manipulating data in simple ways.
We will create a JSON object form POJO and vice versa now which is generally called as serialization and deserialization using Jackson APIs.
serialization – Convert Employee class object to JSON representation or Object
deserialization – reverse of serializing . Convert a JSON Object to Employee class object
package RestAssuredPojo;
import org.testng.annotations.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EmployeeSerializationDeserialization {
@Test
public void createEmployeeJSONFromEmployeePOJOClass() throws JsonProcessingException
{
// Just create an object of Pojo class
Employee employee = new Employee();
// Set value as you wish
employee.setFirstName("Phani");
employee.setLastName("Nagula");
employee.setAge(45);
employee.setGender("Male");
employee.setSalary(50000);
employee.setMarried(true);
// Converting a Java class object to a JSON payload as string
ObjectMapper objectMapper = new ObjectMapper();
String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
System.out.println(employeeJson);
}
@Test
public void getPojoFromEmployeeObject() throws JsonProcessingException
{
// Just create an object of Pojo class
Employee employee = new Employee();
// Set value as you wish
employee.setFirstName("Phani");
employee.setLastName("Nagula");
employee.setAge(45);
employee.setGender("Male");
employee.setSalary(50000);
employee.setMarried(true);
// Converting a Java class object to a JSON payload as string
ObjectMapper objectMapper = new ObjectMapper();
String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
// Converting Employee json string to Employee class object
Employee employee2 = objectMapper.readValue(employeeJson, Employee.class);
System.out.println("First Name of employee : "+employee2.getFirstName());
System.out.println("Last Name of employee : "+employee2.getLastName());
System.out.println("Age of employee : "+employee2.getAge());
System.out.println("Gender of employee : "+employee2.getGender());
System.out.println("Salary of employee : "+employee2.getSalary());
System.out.println("Marital status of employee : "+employee2.getMarried());
}
}
Simple Json Array Object:
[
{
“firstName”: “Phani”,
“lastName”: “Nagula”,
“gender”: “Male”,
“age”: 45,
“salary”: 50000,
“married”: true
}
]
Create POJO Class:
package RestAssuredPojo;
public class Employee {
// private variables or data members of pojo class
private String firstName;
private String lastName;
private String gender;
private int age;
private double salary;
private boolean married;
// Getter and setter methods
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public boolean getMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
}
package RestAssuredPojo;
import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ListOfEmployeesSerializationDeserialization {
public String allEmployeeJson;
@Test
public void createListOfEmployeesJSONArrayFromEmployeePOJOClass() throws JsonProcessingException {
// Create first employee
Employee phani = new Employee();
amod.setFirstName("Phani");
amod.setLastName("Nagula");
amod.setAge(45);
amod.setGender("Male");
amod.setSalary(50000);
amod.setMarried(true);
// Creating a List of Employees
List allEmployees = new ArrayList();
allEmployees.add(phani );
// Converting a Java class object to a JSON Array payload as string
ObjectMapper objectMapper = new ObjectMapper();
allEmployeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(allEmployees);
System.out.println(allEmployeeJson);
}
@Test
public void getPojoFromEmployeeObject() throws JsonProcessingException {
// Converting EMployee json Array string to Employee class object
ObjectMapper objectMapper = new ObjectMapper();
List allEmploeesDetails = objectMapper.readValue(allEmployeeJson,
new TypeReference<List>() {
});
for (Employee emp : allEmploeesDetails) {
System.out.println("========================================================");
System.out.println("First Name of employee : " + emp.getFirstName());
System.out.println("Last Name of employee : " + emp.getLastName());
System.out.println("Age of employee : " + emp.getAge());
System.out.println("Gender of employee : " + emp.getGender());
System.out.println("Salary of employee : " + emp.getSalary());
System.out.println("Marital status of employee : " + emp.getMarried());
System.out.println("========================================================");
}
}
}