API testing has become a fundamental part of modern software development because applications today heavily rely on communication between services. Whether it is a web application, mobile platform, cloud-native service, or microservice architecture, APIs act as the backbone for data exchange. Among all HTTP methods used in API testing, the PUT request plays a critical role because it is commonly used to update existing resources on the server.

REST Assured is one of the most popular Java libraries for API automation testing. It simplifies the process of validating REST APIs by offering a readable and expressive syntax. Developers and QA engineers widely prefer REST Assured because it integrates seamlessly with Java testing frameworks such as JUnit and TestNG.

In this article, you will learn how to test PUT requests using REST Assured in Java. The article covers the basics of PUT requests, project setup, request creation, response validation, authentication handling, JSON payload management, advanced assertions, and best practices. Multiple coding examples are also included to help you understand the implementation in real-world scenarios.

Understanding PUT Requests in REST APIs

A PUT request is an HTTP method used to update an existing resource on the server. Unlike POST requests, which are generally used to create new resources, PUT requests replace or update the target resource with the provided data.

For example, suppose there is an API endpoint for user management:

PUT /users/101

This endpoint updates the user with ID 101.

A typical PUT request contains:

  • Endpoint URL
  • Headers
  • Authentication token (if required)
  • Request body containing updated data

The server processes the request and returns a response indicating whether the update was successful.

Example JSON payload:

{
  "name": "John Smith",
  "email": "johnsmith@example.com",
  "job": "Senior QA Engineer"
}

Why Use REST Assured for PUT Request Testing

REST Assured provides several benefits for API automation:

  • Easy-to-read syntax
  • Native Java integration
  • Powerful assertions
  • JSON and XML parsing support
  • Authentication handling
  • Logging and debugging features
  • Compatibility with CI/CD pipelines

It reduces boilerplate code significantly compared to traditional HTTP libraries.

For example, instead of manually creating HTTP connections, REST Assured allows concise API tests like this:

given()
    .header("Content-Type", "application/json")
    .body(payload)
.when()
    .put("/users/101")
.then()
    .statusCode(200);

Setting Up REST Assured in Java

Before testing PUT requests, you need to configure REST Assured in your Java project.

Maven Dependency

Add the following dependency to your pom.xml file:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.4.0</version>
    <scope>test</scope>
</dependency>

TestNG Dependency

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.9.0</version>
    <scope>test</scope>
</dependency>

JUnit Dependency

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.10.1</version>
    <scope>test</scope>
</dependency>

After adding dependencies, refresh the Maven project.

Basic Structure of a REST Assured PUT Request

REST Assured follows the BDD (Behavior Driven Development) syntax:

given()
.when()
.then()
  • given() specifies request details
  • when() performs the action
  • then() validates the response

Basic PUT request example:

import io.restassured.RestAssured;
import io.restassured.http.ContentType;

public class PutRequestExample {

    public static void main(String[] args) {

        String requestBody = "{\n" +
                "    \"name\": \"John Smith\",\n" +
                "    \"job\": \"QA Lead\"\n" +
                "}";

        RestAssured
            .given()
                .baseUri("https://reqres.in/api")
                .contentType(ContentType.JSON)
                .body(requestBody)
            .when()
                .put("/users/2")
            .then()
                .statusCode(200)
                .log().all();
    }
}

This example sends a PUT request to update user details and validates that the server returns HTTP status code 200.

Testing PUT Requests With JSON Payload

Most REST APIs accept JSON data in PUT requests.

Example:

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;

public class UpdateUserTest {

    @Test
    public void updateUser() {

        String payload = "{\n" +
                "  \"name\": \"Michael\",\n" +
                "  \"job\": \"Automation Tester\"\n" +
                "}";

        RestAssured
            .given()
                .baseUri("https://reqres.in/api")
                .contentType(ContentType.JSON)
                .body(payload)
            .when()
                .put("/users/2")
            .then()
                .statusCode(200)
                .log().body();
    }
}

This test validates whether the user update operation succeeds.

Validating Response Data in PUT Requests

Validating only the status code is not enough. A proper API test should verify the response body as well.

Example with assertions:

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class ResponseValidationTest {

    public static void main(String[] args) {

        String requestBody = "{\n" +
                "    \"name\": \"David\",\n" +
                "    \"job\": \"API Tester\"\n" +
                "}";

        given()
            .baseUri("https://reqres.in/api")
            .contentType("application/json")
            .body(requestBody)
        .when()
            .put("/users/2")
        .then()
            .statusCode(200)
            .body("name", equalTo("David"))
            .body("job", equalTo("API Tester"))
            .body("updatedAt", notNullValue());
    }
}

This test validates:

  • Status code
  • Name field
  • Job field
  • Presence of update timestamp

Using HashMap for Dynamic PUT Request Payloads

Instead of hardcoding JSON strings, you can use Java collections to build payloads dynamically.

Example:

import java.util.HashMap;
import io.restassured.RestAssured;

public class HashMapPayloadExample {

    public static void main(String[] args) {

        HashMap<String, String> data = new HashMap<>();

        data.put("name", "Sophia");
        data.put("job", "Senior Developer");

        RestAssured
            .given()
                .baseUri("https://reqres.in/api")
                .contentType("application/json")
                .body(data)
            .when()
                .put("/users/2")
            .then()
                .statusCode(200)
                .log().all();
    }
}

This approach improves maintainability and flexibility.

Sending PUT Requests Using POJO Classes

A cleaner approach is to use Plain Old Java Objects (POJO).

Create POJO Class

public class User {

    private String name;
    private String job;

    public User(String name, String job) {
        this.name = name;
        this.job = job;
    }

    public String getName() {
        return name;
    }

    public String getJob() {
        return job;
    }
}

Test Class

import static io.restassured.RestAssured.*;

public class POJOPutRequest {

    public static void main(String[] args) {

        User user = new User("Emma", "DevOps Engineer");

        given()
            .baseUri("https://reqres.in/api")
            .contentType("application/json")
            .body(user)
        .when()
            .put("/users/2")
        .then()
            .statusCode(200)
            .log().body();
    }
}

Using POJOs makes the code more scalable and easier to manage.

Adding Headers in PUT Requests

Headers are often required in API communication.

Common headers include:

  • Authorization
  • Content-Type
  • Accept

Example:

given()
    .baseUri("https://reqres.in/api")
    .header("Content-Type", "application/json")
    .header("Accept", "application/json")
    .body(payload)
.when()
    .put("/users/2")
.then()
    .statusCode(200);

Headers ensure proper communication between client and server.

Handling Authentication in PUT Requests

Many APIs require authentication.

REST Assured supports several authentication mechanisms.

Basic Authentication Example

given()
    .auth()
    .basic("admin", "password123")
    .contentType("application/json")
    .body(payload)
.when()
    .put("/users/2")
.then()
    .statusCode(200);

Bearer Token Authentication Example

given()
    .header("Authorization", "Bearer your_token_here")
    .contentType("application/json")
    .body(payload)
.when()
    .put("/users/2")
.then()
    .statusCode(200);

Authentication testing is essential for secure APIs.

Logging PUT Requests and Responses

Logging helps during debugging.

REST Assured provides detailed logs.

Example:

given()
    .log().all()
    .contentType("application/json")
    .body(payload)
.when()
    .put("/users/2")
.then()
    .log().all();

This logs:

  • Headers
  • Request body
  • Response body
  • Status code

Validating Response Time

Performance validation is another important aspect of API testing.

Example:

given()
    .contentType("application/json")
    .body(payload)
.when()
    .put("/users/2")
.then()
    .statusCode(200)
    .time(lessThan(3000L));

This validates that the response time is under 3 seconds.

Using Path Parameters in PUT Requests

Path parameters help make endpoints dynamic.

Example:

given()
    .pathParam("id", 2)
    .contentType("application/json")
    .body(payload)
.when()
    .put("/users/{id}")
.then()
    .statusCode(200);

This approach improves test readability.

Using External JSON Files for PUT Requests

Maintaining payloads in external files is useful for large projects.

Example JSON file (updateUser.json):

{
  "name": "Robert",
  "job": "Software Architect"
}

Java code:

import java.io.File;

given()
    .contentType("application/json")
    .body(new File("src/test/resources/updateUser.json"))
.when()
    .put("/users/2")
.then()
    .statusCode(200);

This improves payload management.

Negative Testing for PUT Requests

Negative testing validates API behavior with invalid data.

Example:

String invalidPayload = "{ \"name\": \"\" }";

given()
    .contentType("application/json")
    .body(invalidPayload)
.when()
    .put("/users/2")
.then()
    .statusCode(400);

Negative tests help identify vulnerabilities and validation issues.

Chaining Requests in REST Assured

In real-world testing, APIs are often chained together.

Example workflow:

  1. Create user
  2. Update user
  3. Retrieve updated user

Example:

int userId = given()
    .contentType("application/json")
    .body(createPayload)
.when()
    .post("/users")
.then()
    .extract()
    .path("id");

given()
    .contentType("application/json")
    .body(updatePayload)
.when()
    .put("/users/" + userId)
.then()
    .statusCode(200);

This simulates real application behavior.

Integrating REST Assured With TestNG

REST Assured integrates well with TestNG.

Example:

import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;

public class PutAPITest {

    @Test
    public void verifyUserUpdate() {

        String payload = "{\n" +
                "  \"name\": \"Chris\",\n" +
                "  \"job\": \"QA Manager\"\n" +
                "}";

        given()
            .baseUri("https://reqres.in/api")
            .contentType("application/json")
            .body(payload)
        .when()
            .put("/users/2")
        .then()
            .statusCode(200)
            .body("name", equalTo("Chris"));
    }
}

TestNG provides reporting and test organization capabilities.

Best Practices for Testing PUT Requests

Below are some best practices for REST Assured PUT request testing:

Use Reusable Methods

Create utility methods for common operations.

Store Endpoints Separately

Avoid hardcoding URLs throughout the framework.

Validate Multiple Response Attributes

Do not rely only on status codes.

Use External Test Data

Maintain JSON files or Excel sheets for scalability.

Implement Logging

Enable logs for debugging failed tests.

Perform Negative Testing

Test invalid payloads and unauthorized access.

Use Assertions Properly

Verify all important fields returned by the API.

Integrate With CI/CD

Run API tests automatically in Jenkins or GitHub Actions.

Common Challenges While Testing PUT Requests

API testers may face several issues:

Incorrect Content-Type

Missing JSON headers can cause server errors.

Invalid Authentication

Expired or invalid tokens lead to authorization failures.

Incomplete Payloads

Some APIs require mandatory fields.

Environment Configuration Issues

Wrong endpoints or test environments can break tests.

Serialization Problems

Improper POJO mapping may cause malformed JSON.

Understanding these issues helps create stable test frameworks.

Real-World Use Cases of PUT Request Testing

PUT requests are widely used in:

  • Updating user profiles
  • Modifying employee records
  • Updating product details
  • Editing banking information
  • Updating inventory systems
  • Modifying healthcare records
  • Updating cloud configurations

API testers validate these operations to ensure business continuity.

Conclusion

Testing PUT requests with REST Assured in Java is an essential skill for modern API automation engineers. Since PUT operations are primarily responsible for updating existing resources, validating them correctly ensures that applications maintain accurate and reliable data across systems.

REST Assured simplifies API testing by providing an expressive and developer-friendly syntax that integrates naturally with Java ecosystems. Instead of writing complex HTTP client code, testers can create clean and readable automation scripts capable of validating endpoints, headers, authentication, response payloads, and performance metrics with minimal effort.

Throughout this article, we explored multiple approaches for testing PUT requests, including raw JSON payloads, HashMap-based payload creation, POJO serialization, external JSON files, authentication handling, path parameters, logging, response validation, and negative testing scenarios. These techniques collectively help testers build scalable and maintainable API automation frameworks.

One of the biggest advantages of REST Assured is its flexibility. Whether you are testing a simple CRUD API or a large enterprise microservice ecosystem, REST Assured provides the tools necessary to automate complex API workflows efficiently. When combined with frameworks like TestNG or JUnit, it becomes even more powerful by supporting assertions, reporting, parallel execution, and CI/CD integration.

Another critical takeaway is the importance of comprehensive validation. Successful API testing is not limited to checking status codes alone. Proper PUT request validation should include response body assertions, schema verification, authentication checks, response time validation, and negative test scenarios. This ensures that APIs behave consistently under both valid and invalid conditions.

Additionally, adopting best practices such as reusable utility methods, centralized configuration management, externalized test data, detailed logging, and modular framework design can dramatically improve long-term maintainability and scalability of API automation projects.

As organizations increasingly adopt cloud computing, distributed systems, and microservices architectures, API testing continues to grow in importance. REST Assured remains one of the most effective and widely used tools for Java-based API automation because of its simplicity, robustness, and extensive feature set.

By mastering PUT request testing with REST Assured, testers and developers can significantly improve API reliability, reduce production defects, enhance application stability, and accelerate software delivery pipelines. Whether you are a beginner entering the field of API automation or an experienced QA engineer building enterprise-grade frameworks, learning REST Assured PUT request testing is a valuable investment that strengthens both technical expertise and software quality assurance capabilities.