How to test POST JSON Object request using Java Map in Rest Assured

HOME

In the last tutorial, I explained How to test POST request from JSON Object in Rest Assured where the request body is built in JSONObject. In this tutorial, I will create a request body using JSON Object in Rest Assured. 

We can create a JSON Object using a Map in Java. 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.

<dependencies>

    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>20231013</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.15.2</version>
    </dependency>

  </dependencies>

I have created a simple Java map and filled it with the values that represent JSON properties.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;

public class Json_Demo {

    @Test
    public void passBodyAsMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("employee_name", "MapTest");
        map.put("employee_salary", "99999");
        map.put("employee_age", "30");
        map.put("profile_image", "test.png");
        RestAssured.given()
                .contentType(ContentType.JSON)
                .body(map)
                .log().all()

                .when()
                .post("https://dummy.restapiexample.com/api/v1/create")

                .then()
                .assertThat().statusCode(200)
                .body("data.employee_name", equalTo("MapTest"))
                .body("data.employee_age", equalTo("30"))
                .body("data.employee_salary", equalTo("99999"))
                .body("message", equalTo("Successfully! Record has been added.")).log().all();
    }
}

The request body as well as the response body will look as shown below:-

Above one is a simple JSON Request Body. Let us take an example of a Complex Request Body or nested Request Body as shown below.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;

public class Json_Demo {

    @Test
    public void passBodyAsMultipleMap() {

        // First JSON Object using Hash Map
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("employee_name", "MapTest");
        data.put("profile_image", "test.png");

        // Second JSON Object using Hash Map
        Map<String, String> msg = new HashMap<String, String>();
        msg.put("updated_message", "Details of New Resource");
        msg.put("employee_age", "30");
        data.put("details", msg);
        data.put("employee_salary", "99999");
        RestAssured.given().contentType(ContentType.JSON).body(data).log().all()
                // WHEN
                .when().post("https://dummy.restapiexample.com/api/v1/create")
                // THEN
                .then().assertThat().statusCode(200).body("data.employee_name", equalTo("MapTest"))
                .body("data.details.updated_message", equalTo("Details of New Resource"))
                .body("data.details.employee_age", equalTo("30")).body("data.employee_salary", equalTo("99999"))
                .body("message", equalTo("Successfully! Record has been added.")).log().all();
    }
}

The request body as well as the response body will look as shown below image. The first part is the body of the request and the second part is the response provided by the API.

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

How to pretty print JSON using the Gson library?

HOME

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+919999988822",
  "emailId" : "abc@test.com"
  }

Let us create a table named Employee which contains the data members same as node names in the above JSON payload and their corresponding getter and setter methods.

public class Employee {

	// private data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// 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 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 String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

We will convert a Java Object to a JSON object as a String and also will write it into a .json file. There are many variations for the method toJson().

You can create a Gson instance by invoking a new Gson() if the default configuration is all you need, as shown in the below example.

  @Test
    public void withoutPretty() {

        // Create an object of POJO class
        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        employee.setSalary(75000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");

        Gson gson = new Gson();
        String employeeJsonPayload = gson.toJson(employee);
        System.out.println("Json :" + employeeJsonPayload);

    }

The execution message is shown below.

public GsonBuilder setPrettyPrinting()

@Test
    public void withPretty() {
        // Create an object of POJO class
        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        employee.setSalary(75000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");

        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        String json = gson.toJson(employee);

        System.out.println("Pretty Json :" + json);

    }

Serenity BDD Tutorials

HOME

Serenity BDD is an open-source library that aims to make the idea of living documentation a reality.
Serenity BDD helps you write cleaner and more maintainable automated acceptance and regression tests faster. Serenity also uses the test results to produce illustrated, narrative reports that document and describe what your application does and how it works. Serenity tells you not only what tests have been executed, but more importantly, what requirements have been tested

Basics of Serenity

Chapter 1 How to run Serenity BDD tests in Chrome Browser
Chapter 2 How to run Serenity BDD tests in Edge Browser
Chapter 3 Testing of Web Application using Serenity with JUnit4
Chapter 4 Integration of Serenity with JUnit5
Chapter 5 Manual Tests in Serenity with JUnit5
Chapter 6 Integration of Serenity with Rest Assured
Chapter 7 Data Driven Tests in Serenity with JUnit
Chapter 8 Data Driven Tests using CSV file in Serenity
Chapter 9 Implicit Wait in Serenity
Chapter 10 Explicit Wait in Serenity
Chapter 11 Fluent Wait in Serenity – NEW
Chapter 12 Serenity Testing on Different Browsers – NEW

Serenity with Cucumber

Chapter 1 Serenity BDD with Cucumber and JUnit4 for Web Application
Chapter 2 Serenity BDD with Cucumber for SpringBoot Application
Chapter 3 Serenity BDD with Cucumber and Rest Assured
Chapter 4 Testing of SpringBoot REST Application using Rest Assured for GET Method
Chapter 5 Serenity Report for Web Application with Cucumber6 and Junit
Chapter 6 Integration of Serenity with Cucumber and JUnit5
 Chapter 7 Testing of SpringBoot Application with Serenity BDD, Cucumber and JUnit5 – NEW

Serenity Reports

Chapter 1 Serenity Report for Web Application with Cucumber6 and Junit
Chapter 2 Serenity Emailable HTML Report
Chapter 3 Serenity Emailable Report in Gradle
Chapter 4 How to report Manual Tests in Serenity Report
Chapter 5 How to attach Test Evidence to Manual Tests in Serenity Report
Chapter 6 How to manage screenshots in Serenity Report
Chapter 7 How to generate Serenity Report in customized path

Serenity with Gradle

Chapter 1 Serenity BDD with Gradle and Cucumber for Web Application
Chapter 2 Serenity BDD with Cucumber and Rest Assured in Gradle

Serenity with CI/CD

Chapter 1 Serenity with Jenkins
Chapter 2 How to create Jenkins pipeline for Serenity tests
Chapter 3 How to run Serenity tests with GitHub Actions
Chapter 4 Run Serenity Tests in GitLab CI/CD

Parallel Testing

Chapter 1 Parallel Execution of Cucumber with Serenity and JUnit5

Exclude Fields from Serialization in Gson – @Expose Annotation

HOME

The previous tutorials have explained the conversion of Java Object to JSON using Gson API. This tutorial explains the process of excluding the attributes from the JSON using Gson API.

@Expose helps control what class attributes can be serialized or deserialized.

@Expose(serialize = false)
private String lastName;

@Expose (serialize = false, deserialize = false)
private String emailAddress

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName": "Vibha",
  "lastName": "Singh",
  "salary": {
    "2018": 14000,
    "2012": 12000,
    "2010": 10000
  },
  "designation": "Manager",
  "emailId": [
    "abc@test.com",
    "vibha@test.com"
  ]
}

Let us create a table named Employee which contains the data members same as node names in the above JSON payload with @Expose annotation and their corresponding getter and setter methods.

package com.example.gson;

import com.google.gson.annotations.Expose;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

public class Employee {

    // private data members of POJO class

    @Expose(serialize = true)
    private String firstName;

    @Expose(serialize = true)
    private String lastName;

    @Expose(serialize = false)
    private int age;

    @Expose(serialize = true)
    private Map<String, BigDecimal> salary;

    @Expose()
    private String designation;

    @Expose(serialize = false)
    private String contactNumber;

    @Expose(serialize = true)
    private List<String> emailId;

    // 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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Map<String, BigDecimal> getSalary() {
        return salary;
    }

    public void setSalary(Map<String, BigDecimal> salary) {
        this.salary = salary;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public List<String> getEmailId() {
        return emailId;
    }

    public void setEmailId(List<String> emailId) {
        this.emailId = emailId;
    }

    @Override
    public String toString() {
        return "(firstName: " + firstName + "," +
                "lastName: " + lastName + "," +
                "age: " + age + ", " +
                "salary: " + salary + "," +
                "designation: " + designation + ", " +
                "contactNumber: " + contactNumber + ", " +
                "emailId: " + emailId + ")";

    }
}

Suppose the attribute age and contactNumber in the Employee class should not serialize because it’s sensitive information. Hence, we must decorate these attributes with the annotation @Expose(serialize=false):

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class GsonExpose_Demo {

    @Test
    public void gsonExposeTest()  {

        // Create an object of POJO class
        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        Map<String, BigDecimal> salary = new HashMap() {{
            put("2010", new BigDecimal(10000));
            put("2012", new BigDecimal(12000));
            put("2018", new BigDecimal(14000));
        }};

        employee.setSalary(salary);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId(Arrays.asList("abc@test.com","vibha@test.com"));

        Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
        String employeeJsonPayload = gson.toJson(employee);
        System.out.println("Json :" + employeeJsonPayload);

    }
}

The output of the above program is shown below.

Cucumber Tutorials

 HOME

Cucumber Introduction, Installation, and Configuration

Chapter 1  Introduction of Cucumber Testing Tool (BDD Tool)
Chapter 2 How to install Cucumber Eclipse Plugin
Chapter 3 How to setup Cucumber with Eclipse
Chapter 4 Cucumber – What is Gherkin

Cucumber Scenario, Features & Step Definition

Chapter 1 Cucumber – What is Feature File in Cucumber
Chapter 2 Step Definition in Cucumber
Chapter 3 Cucumber – JUnit Test Runner Class

Cucumber – Hooks & Tags

Chapter 1 Hooks in Cucumber
Chapter 2 Tags in Cucumber
Chapter 3 Conditional Hooks in Cucumber
Chapter 4 What is CucumberOptions in Cucumber?
Chapter 5 Background in Cucumber
Chapter 6 Monochrome in Cucumber
Chapter 7 What is Glue in Cucumber?

Cucumber – Data Driven Testing

Chapter 1 Data Driven Testing using Scenario Outline in Cucumber
Chapter 2 DataTables in Cucumber

Cucumber Integration with Selenium – Maven

Chapter 1 Integration of Cucumber with Selenium and JUnit4
Chapter 2 Integration of Cucumber with Selenium and TestNG
Chapter 3 Page Object Model with Selenium, Cucumber and JUnit
Chapter 4 Page Object Model with Selenium, Cucumber, and TestNG
Chapter 5 Integration of Cucumber7 with Selenium and JUnit5
Chapter 6 Run Cucumber7 with JUnit5 Tests from Maven Command Line
Chapter 7 How to rerun failed tests in Cucumber
Chapter 8 How to create Cucumber Report after rerun of failed tests – NEW
Chapter 9 How to rerun failed tests twice in Cucumber – NEW

Cucumber – Command Line Execution

Chapter 1 Run Cucumber Test from Command Line
Chapter 2 Run Gradle Cucumber Tests from Command Line

Cucumber Integration with Rest API

Chapter 1 Rest API Test in Cucumber BDD
Chapter 2 How To Create Gradle Project with Cucumber to test Rest API

Cucumber Integration with SpringBoot

Chapter 1 Integration Testing of Springboot with Cucumber and JUnit4
Chapter 2 Integration Testing of Springboot with Cucumber and TestNG

Cucumber – Reporting

Chapter 1 Cucumber Tutorial – Cucumber Reports
Chapter 2 Cucumber Report Service
Chapter 3 Implemention of ‘Masterthought’ Reports in Cucumber
Chapter 4 Implemention of ‘Masterthought’ Reports in Cucumber with JUnit4

Cucumber Integration with Allure Reports

Chapter 1 Allure Report with Cucumber5, Selenium and JUnit4
Chapter 2 Allure Report with Cucumber5, Selenium and TestNG
Chapter 3 Integration of Allure Report with Rest Assured and JUnit4
Chapter 4 Integration of Allure Report with Rest Assured and TestNG
Chapter 5 Gradle – Allure Report for Selenium and TestNG

Cucumber Integration with Extent Reports

Chapter 1 ExtentReports Version 5 for Cucumber 6 and TestNG
Chapter 2 How to add Screenshot to Cucumber ExtentReports
Chapter 3 ExtentReports Version 5 for Cucumber 6 and JUnit4
Chapter 4 PDF ExtentReport for Cucumber and TestNG
Chapter 5 ExtentReports Version 5 for Cucumber 7 and TestNG
Chapter 6 Extent Reports Version 5 for Cucumber7 and JUnit5

Cucumber – Parallel Execution

Chapter 1 Parallel Testing in Cucumber with JUnit
Chapter 2 Parallel Testing in Cucumber with TestNG
Chapter 3 Dependency Injection in Cucumber using Pico-Container

How to read JSON from File Using Gson API

HOME

The previous tutorials have explained the conversion of Java Object to JSON using Gson API. This tutorial explains the process of reading the JSON Payload from a file using Gson API.

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects, including pre-existing objects for those you do not have source code.

  • Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice versa.

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName": "Vibha",
  "lastName": "Singh",
  "age": 30,
  "salary": {
    "2023": 74000,
    "2022": 62000,
    "2021": 50000
  },
  "designation": "Manager",
  "contactNumber": "+919999988822",
  "emailId": "abc@test.com"
}

Let us create a table named Employee which contains the data members same as node names in the above JSON payload and their corresponding getter and setter methods.

import java.math.BigDecimal;
import java.util.Map;

public class Employee {

    // private data members of POJO class
    private String firstName;
    private String lastName;
    private int age;
    private Map<String, BigDecimal> salary;
    private String designation;
    private String contactNumber;
    private String emailId;

    // 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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Map<String, BigDecimal> getSalary() {
        return salary;
    }

    public void setSalary(Map<String, BigDecimal> salary) {
        this.salary = salary;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    @Override
    public String toString() {
        return "(firstName: " + firstName + "," +
                "lastName: " + lastName + "," +
                "age: " + age + ", " +
                "salary: " + salary + "," +
                "designation: " + designation + ", " +
                "contactNumber: " + contactNumber + ", " +
                "emailId: " + emailId + ")";

    }
}

We will convert a JSON Object to a Java Object.

You can create a Gson instance by invoking a new Gson() if the default configuration is all you need, as shown in the below example.

import org.junit.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;

public class GsonReadFromFile {

    @Test
    public void readJsonFromFile() throws FileNotFoundException {

        String userDir = System.getProperty("user.dir");
        File jsonFilePath = new File(userDir + "\\src\\test\\resources\\Employee.json");
        FileReader fileReader = new FileReader(jsonFilePath);

        Gson gson = new Gson();
        Employee employee = gson.fromJson(fileReader, Employee.class);
        System.out.println(employee.toString());

        System.out.println("FirstName :" + employee.getFirstName());
        System.out.println("LastName :" + employee.getLastName());
        System.out.println("Age :" + employee.getAge());
        System.out.println("Salary :" + employee.getSalary());
        System.out.println("Designation :" + employee.getDesignation());
        System.out.println("ContactNumber :" + employee.getContactNumber());
        System.out.println("EmailId :" + employee.getEmailId());


    }
}

The execution message is shown below.

How to save Json in File Using Gson API

HOME

The previous tutorials have explained the conversion of Java Object to JSON using Gson API. This tutorial explains the process of saving JSON Payload in a file using Gson API.

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects, including pre-existing objects those you do not have source code.

  • Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice versa.
  • Allow pre-existing unmodifiable objects to be converted to and from JSON.
  • Extensive support of Java Generics.
  • Allow custom representations for objects.
  • Support arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types).

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+919999988822",
  "emailId" : "abc@test.com"
  }

Let us create a table named Employee which contains the data members same as node names in the above JSON payload and their corresponding getter and setter methods.

public class Employee {

	// private data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// 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 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 String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

We will convert a Java Object to a JSON object as a String and also will write it into a .json file. There are many variations for the method toJson().

You can create a Gson instance by invoking a new Gson() if the default configuration is all you need, as shown in the below example.

You can also use GsonBuilder to build a Gson instance with various configuration options such as versioning support, pretty-printing, custom JsonSerializer, JsonDeserializer.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Test;
import java.io.File;
import java.io.FileWriter;

public class WriteJsonFileDemo {

    @Test
    public void saveJsonToFile() {

        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        employee.setSalary(75000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");

        Gson builder = new GsonBuilder().setPrettyPrinting().create();
        String employeePrettyJsonPayload = builder.toJson(employee);
        System.out.println(employeePrettyJsonPayload);

        String userDir = System.getProperty("user.dir");
        File outputJsonFile = new File(userDir + "\\src\\test\\resources\\testData\\EmployeePayloadUsingGson.json");
        try {
            FileWriter fileWriter = new FileWriter(outputJsonFile);
            builder.toJson(employee, fileWriter);
            fileWriter.flush();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

The execution message is shown below.

Serialization – How to convert Java Object To JSON Object Using Gson API

HOME

The previous tutorials have explained the conversion of Java Object to JSON and JSON payload to Java Objects using Jackson API. This tutorial explains the process to convert Java Object to JSON Payload using Gson API.

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects, including pre-existing objects those you do not have source code.

  • Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice-versa.
  • Allow pre-existing unmodifiable objects to be converted to and from JSON.
  • Extensive support of Java Generics.
  • Allow custom representations for objects.
  • Support arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types).

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+919999988822",
  "emailId" : "abc@test.com"
  }

Let us create a table named Employee which contains the data members same as node names in the above JSON payload and their corresponding getter and setter methods.

public class Employee {

	// private data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// 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 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 String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

We will convert a Java Object to a JSON object as a String and also will write it into a .json file. There are many variations for the method toJson().

You can create a Gson instance by invoking a new Gson() if the default configuration is all you need, as shown in the below example.

You can also use GsonBuilder to build a Gson instance with various configuration options such as versioning support, pretty-printing, custom JsonSerializer, JsonDeserializer.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Test;

public class EmployeeGsonTest {

    @Test
    public void gsonSerializationTest()  {

        // Create an object of POJO class
        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        employee.setSalary(75000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");

        Gson gson = new Gson();
        String employeeJsonPayload = gson.toJson(employee);
        System.out.println("Json :" + employeeJsonPayload);

        Gson builder = new GsonBuilder().setPrettyPrinting().create();
        String employeePrettyJsonPayload = builder.toJson(employee);
        System.out.println("Pretty Json :" + employeePrettyJsonPayload);

    }
}

The execution message is shown below.

Integration Testing of SpringBoot Application with Serenity BDD, Cucumber and JUnit4

HOME

Relationship between SpringBoot, Serenity BDD, Cucumber and Rest Assured

Implementation Steps

  1. Create a source folder – src/test/resources to create test scenarios in the Feature file
  2. Add SpringBoot, Serenity, Cucumber, and JUnit4 dependencies to the project
  3. Create a feature file under src/test/resources
  4. Create the StepDefinition and Helper classes.
  5. Create a Serenity Runner class in the src/test/java directory
  6. Run the tests from JUnit
  7. Run the tests from Command Line
  8. Serenity Report Generation
  9. Cucumber Report Generation

Step 1 – Create a source folder – src/test/resources

Right-click on the test directory and select New->Directory and select resources (Maven Source Directories). Create a source folder – src/test/resources to create test scenarios in the Feature file

Step 2 – Add SpringBoot, Serenity, Cucumber, and JUnit4 dependencies to the project

We have added SpringBootTest, Serenity, Cucumber, JUnit4, and JUnit Vintage.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>Springboot_Serenity_Demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Springboot_Serenity_Demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
        <serenity.version>3.6.12</serenity.version>
        <maven.surefire.plugin.version>3.0.0-M9</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.0.0-M9</maven.failsafe.plugin.version>
        <parallel.tests></parallel.tests>
        <maven.compiler.plugin.plugin>3.10.1</maven.compiler.plugin.plugin>
        <maven.compiler.source.version>11</maven.compiler.source.version>
        <maven.compiler.target.version>11</maven.compiler.target.version>
        <tags></tags>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

		<!-- Serenity Core -->
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-core</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

		<!-- Serenity With JUnit4 -->
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-junit</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

		<!-- Serenity With Rest Assured -->
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-rest-assured</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Serenity With Cucumber -->
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-cucumber</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Serenity With Spring -->
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-spring</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>SpringRunnerTests.java</include>
                        <include>**/Test*.java</include>
                    </includes>
                    <parallel>methods</parallel>
                    <threadCount>${parallel.tests}</threadCount>
                    <forkCount>${parallel.tests}</forkCount>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.plugin}</version>
                <configuration>
                    <source>${maven.compiler.source.version}</source>
                    <target>${maven.compiler.target.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>net.serenity-bdd.maven.plugins</groupId>
                <artifactId>serenity-maven-plugin</artifactId>
                <version>${serenity.version}</version>
                <configuration>
                    <tags>${tags}</tags>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>net.serenity-bdd</groupId>
                        <artifactId>serenity-core</artifactId>
                        <version>${serenity.version}</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <id>serenity-reports</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>aggregate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>

</project>

Step 3 – Create a feature file under src/test/resources

Below is an example of a feature file which shows a sample test scenario.

Feature: SpringBoot Request
   
@ReceiveCorrectResponse

   Scenario Outline: Send a valid Request to get correct response
    Given I send a request to the URL "<url>"
    Then the response will return "<response>"

   Examples:
   | url             | response                   |
   | /               | Hello World, Spring Boot!  |
   | /qaautomation   | Hello QA Automation!       |

The test class mentioned below (AbstractRestAssuredHelper) contains integration tests for the spring boot rest controller mentioned. This test class:

  • uses @SpringBootTest annotation which loads the actual application context.
  • uses WebEnvironment.RANDOM_PORT to create and run the application at some random server port.
  • @LocalServerPort gets the reference of the port where the server has started. It helps in building the actual request URIs to mimic real client interactions.

Step 4 – Create the StepDefinition and Helper classes

Below is the code of the StepDefinition and Helper class. These classes are created in the src/test/java directory.

AbstractRestAssuredHelper

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import net.serenitybdd.rest.SerenityRest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public abstract class AbstractRestAssuredHelper {
     private final static String BASE_URI = "http://localhost";
 
     @LocalServerPort
     private int port;
 
     protected void configureRestAssured() {
           RestAssured.baseURI = BASE_URI;
           RestAssured.port = port;    
 
     }

     protected RequestSpecification getAnonymousRequest() {
           configureRestAssured();
           return SerenityRest.given();
     }
}

This class sends the request and receives a response after performing the GET operation. Here, the validation of the response also takes place by asserting the expected and actual response

To use Rest-assured, Serenity provides the class SerenityRest

import org.junit.Assert;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.restassured.response.Response;
import net.serenitybdd.rest.SerenityRest;
import net.thucydides.core.annotations.Steps;

public class SpringBootDemoDefinitions {

	@Steps
    AbstractRestAssuredHelper helper;
    private Response response;

    @Given("I send a request to the URL {string}")
    public void iSendARequest(String endpoint) throws Exception  {
         response = helper.getAnonymousRequest().contentType("application/json")
                    .header("Content-Type", "application/json").when().get(endpoint);
    }

    @Then("the response will return {string}")
    public void extractResponse(String Expected ) {
          SerenityRest.restAssuredThat(response -> response.statusCode(200));
          String Actual = response.asString();    
          Assert.assertEquals(Expected, Actual); 
    }
}

Step 5 – Create a Serenity Runner class in the src/test/java directory

We cannot run a Feature file on its own in cucumber-based framework. We need to create a Java class that will run the Feature File. It is the starting point for JUnit to start executing the tests. TestRunner class is created under src/ test/javaWhen you run the tests with serenity, you use the CucumberWithSerenity test runner. If the feature files are not in the same package as the test runner class, you also need to use the @CucumberOptions class to provide the root directory where the feature files can be found.

import org.junit.runner.RunWith;
import io.cucumber.junit.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;

@RunWith(CucumberWithSerenity.class)
@CucumberOptions(features = "src/test/resources", tags = "", glue = "com.example.Springboot_Serenity_Demo.definitions", publish = true)

public class SpringRunnerTests {

}

Step 6 – Run the tests from JUnit

You can run the tests from SpringRunnerTests class. Right-click on the class and select Run ‘SpringRunnerTests’.

Step 7 – Run the tests from Command Line

Run the tests from the command line by using the below command

mvn clean verify

The output of the above program is

The test execution status is shown below:

Step 8 – Serenity Report Generation

By default, the test report generated by Serenity is placed under target/site/serenity/index.html. Below is the sample Serenity Report.

Go to the Test Results tab and we can see all the test scenarios.

Step 9 – Cucumber Report Generation

Cucumber Report can be generated by adding publish=true in SpringRunnerTests as shown in the above example. Click on the link provided in the execution status.

Cucumber Report

The next tutorial explains about the Testing of SpringBoot REST Application using Serenity BDD and Rest Assured for GET Method.

The complete code can be found in GitHub.

How to test PATCH Request using Rest Assured

HOME

In the last tutorial, I explained How to test POST Request using Rest Assured. In this tutorial, I will automate a PATCH Request using Rest Assured. I will verify the status code, line of Status, and content of the Response.

To set up a basic Rest Assured Maven Project, click here and Gradle project, click here.

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>test</scope>
</dependency>
  
<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
</dependency>

What is the PATCH Method?

The HTTP PATCH request method applies partial modifications to a resource

Below are the steps to test a PATCH Request using Rest Assured:

The steps to test the PATCH request are similar to the PUT request.

Below is the example for the test to PATCH method. (Non BDD)

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;

public class Patch_NonBDDDemo {

    RequestSpecification requestSpecification;
    Response response;
    ValidatableResponse validatableResponse;

    @Test
    public void updateUser() {

        String jsonString = "{\"name\": \"William\"}";

        RestAssured.baseURI = "https://reqres.in/api/users/2";

        // Create a request specification
        requestSpecification = RestAssured.given();

        // Setting content type to specify format in which request payload will be sent.
        requestSpecification.contentType(ContentType.JSON);

        // Adding body as string
        requestSpecification.body(jsonString);

        // Calling PATCH method
        response = requestSpecification.patch();

        // Let's print response body.
        String responseString = response.prettyPrint();

        /*
         * To perform validation on response, we need to get ValidatableResponse type of
         * response
         */
        validatableResponse = response.then();

        // Get status code
        validatableResponse.statusCode(200);

        // It will check if status line is as expected
        validatableResponse.statusLine("HTTP/1.1 200 OK");

        // Check response - name attribute
        validatableResponse.body("name", equalTo("William"));

    }
}

Test implemented in BDD Format

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.equalTo;

public class Patch_BDDDemo {

    RequestSpecification requestSpecification;
    Response response;
    ValidatableResponse validatableResponse;

    @Test
    public void updateUser() {

       String jsonString = "{\"name\": \"William\"}";

        // Update name
        validatableResponse = given()
                .baseUri("https://reqres.in/api/users/2")
                .contentType(ContentType.JSON)
                .body(jsonString)
                .when()
                .patch()
                .then()
                .assertThat().statusCode(200)
                .body("name", equalTo("William"));

        System.out.println("Response :" + validatableResponse.extract().asPrettyString());

    }

}

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!