API testing has become a fundamental part of modern software development. As applications increasingly rely on RESTful services, developers and QA engineers need efficient ways to validate APIs quickly and accurately. Among the various HTTP methods used in REST APIs, the PATCH method is especially important because it allows partial updates to resources instead of replacing the entire object.

When performing API automation in Java, REST Assured is one of the most widely used frameworks because of its simplicity, readability, and seamless integration with testing tools like JUnit and TestNG. Testing PATCH requests using REST Assured helps ensure that APIs correctly update only the intended fields while maintaining data integrity.

This article provides a detailed explanation of how to test PATCH requests using REST Assured in Java, including setup instructions, coding examples, validation techniques, best practices, and common pitfalls.

Understanding PATCH Requests in REST APIs

Before diving into implementation, it is important to understand what PATCH requests are and how they differ from PUT requests.

A PATCH request updates only specific fields of an existing resource. Unlike PUT, which replaces the complete object, PATCH modifies only the supplied attributes.

For example, consider the following user object:

{
  "id": 101,
  "name": "John",
  "email": "john@example.com",
  "status": "active"
}

If you want to update only the status field, a PATCH request would send:

{
  "status": "inactive"
}

The remaining fields remain unchanged.

PATCH requests are commonly used for:

  • Updating user profiles
  • Changing account status
  • Editing configuration settings
  • Updating order states
  • Modifying partial resource data

Because PATCH operations affect only selective fields, testing them properly is extremely important.

What Is REST Assured?

REST Assured is a Java-based library designed for testing RESTful APIs. It simplifies HTTP request handling and response validation using a clean and expressive syntax.

Key benefits include:

  • Easy API request creation
  • JSON and XML validation support
  • Integration with JUnit and TestNG
  • Authentication support
  • Schema validation
  • Logging and debugging features

REST Assured follows a Behavior Driven Development (BDD) style using:

given()
when()
then()

This makes test cases highly readable and maintainable.

Setting Up REST Assured in Java

To begin testing PATCH requests, you first 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>

For TestNG support:

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

For JUnit:

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

Basic Structure of a PATCH Request in REST Assured

A PATCH request in REST Assured generally follows this structure:

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

The steps are:

  1. Define request headers and body
  2. Send PATCH request
  3. Validate response

Simple PATCH Request Example

Let us start with a simple example.

Suppose the API endpoint is:

https://reqres.in/api/users/2

We want to update the user’s job title.

Example Code

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;

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

public class PatchRequestTest {

    @Test
    public void updateUserJob() {

        String requestBody = "{\n" +
                "    \"job\": \"Senior QA Engineer\"\n" +
                "}";

        given()
                .baseUri("https://reqres.in")
                .contentType(ContentType.JSON)
                .body(requestBody)

        .when()
                .patch("/api/users/2")

        .then()
                .statusCode(200)
                .body("job", equalTo("Senior QA Engineer"))
                .log().all();
    }
}

Explanation of the Code

Let us break down the code step-by-step.

Base URI

.baseUri("https://reqres.in")

Defines the server URL.

Content Type

.contentType(ContentType.JSON)

Specifies that the request body is JSON.

Request Body

.body(requestBody)

Contains the fields to update.

PATCH Method

.patch("/api/users/2")

Sends the PATCH request.

Response Validation

.statusCode(200)
.body("job", equalTo("Senior QA Engineer"))

Verifies that:

  • Status code is correct
  • Response body contains updated value

Using HashMap for Dynamic PATCH Payloads

Instead of manually writing JSON strings, you can use a HashMap.

Example

import java.util.HashMap;
import java.util.Map;

@Test
public void patchUsingHashMap() {

    Map<String, Object> payload = new HashMap<>();

    payload.put("job", "Automation Architect");

    given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/api/users/2")

    .then()
            .statusCode(200)
            .body("job", equalTo("Automation Architect"));
}

This approach is cleaner and easier to maintain.

Validating Response Headers

PATCH response validation should also include headers.

Example

@Test
public void validateHeaders() {

    String payload = "{ \"job\": \"DevOps Engineer\" }";

    given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/api/users/2")

    .then()
            .statusCode(200)
            .header("Content-Type", containsString("application/json"));
}

Header validation ensures API compliance.

Extracting Response Data

Sometimes you need to extract response values for further validation.

Example

import io.restassured.response.Response;

@Test
public void extractPatchResponse() {

    String payload = "{ \"job\": \"Backend Developer\" }";

    Response response = given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/api/users/2");

    String updatedJob = response.jsonPath().getString("job");

    System.out.println("Updated Job: " + updatedJob);
}

This is useful for chained API validations.

Using POJO Classes for PATCH Requests

For enterprise-level automation frameworks, using POJO classes is recommended.

Create Request POJO

public class PatchRequest {

    private String job;

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

Test Class

@Test
public void patchUsingPojo() {

    PatchRequest request = new PatchRequest();
    request.setJob("Tech Lead");

    given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(request)

    .when()
            .patch("/api/users/2")

    .then()
            .statusCode(200)
            .body("job", equalTo("Tech Lead"));
}

POJO-based payload handling improves maintainability and readability.

Testing Authentication with PATCH Requests

Many APIs require authentication tokens.

Example Using Bearer Token

@Test
public void patchWithAuthToken() {

    String token = "your_access_token";

    String payload = "{ \"status\": \"inactive\" }";

    given()
            .baseUri("https://api.example.com")
            .header("Authorization", "Bearer " + token)
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/users/101")

    .then()
            .statusCode(200);
}

Authentication testing is critical for secure APIs.

Sending PATCH Requests with Path Parameters

REST Assured supports dynamic path parameters.

Example

@Test
public void patchUsingPathParam() {

    String payload = "{ \"job\": \"Manager\" }";

    given()
            .baseUri("https://reqres.in")
            .pathParam("userId", 2)
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/api/users/{userId}")

    .then()
            .statusCode(200);
}

This approach improves flexibility.

Sending PATCH Requests with Query Parameters

Some APIs use query parameters alongside PATCH requests.

Example

@Test
public void patchWithQueryParam() {

    String payload = "{ \"role\": \"admin\" }";

    given()
            .baseUri("https://api.example.com")
            .queryParam("notify", true)
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/users/10")

    .then()
            .statusCode(200);
}

Negative Testing for PATCH Requests

Negative testing ensures the API behaves correctly under invalid conditions.

Invalid Endpoint Example

@Test
public void patchInvalidEndpoint() {

    String payload = "{ \"job\": \"Tester\" }";

    given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/api/unknown")

    .then()
            .statusCode(404);
}

Testing Invalid Payloads

Example

@Test
public void patchInvalidPayload() {

    String payload = "{ invalid json }";

    given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/api/users/2")

    .then()
            .statusCode(400);
}

Negative scenarios improve API robustness.

Logging Requests and Responses

Logging is useful for debugging failed tests.

Example

@Test
public void patchWithLogging() {

    String payload = "{ \"job\": \"Architect\" }";

    given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(payload)
            .log().all()

    .when()
            .patch("/api/users/2")

    .then()
            .log().all()
            .statusCode(200);
}

Logs help identify issues quickly.

Using Specifications in REST Assured

Request specifications reduce code duplication.

Example

import io.restassured.specification.RequestSpecification;

@Test
public void patchUsingSpecification() {

    RequestSpecification requestSpec = given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON);

    String payload = "{ \"job\": \"Director\" }";

    requestSpec
            .body(payload)

    .when()
            .patch("/api/users/2")

    .then()
            .statusCode(200);
}

Specifications improve framework scalability.

Validating JSON Schema for PATCH Responses

Schema validation ensures response structure consistency.

Example

@Test
public void validatePatchSchema() {

    String payload = "{ \"job\": \"Consultant\" }";

    given()
            .baseUri("https://reqres.in")
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/api/users/2")

    .then()
            .statusCode(200)
            .body(matchesJsonSchemaInClasspath("patch-schema.json"));
}

Schema validation prevents unexpected response changes.

Integrating PATCH Tests with TestNG

REST Assured works well with TestNG.

Example

import org.testng.annotations.Test;

public class PatchTestNG {

    @Test
    public void updateUser() {

        String payload = "{ \"job\": \"QA Lead\" }";

        given()
                .baseUri("https://reqres.in")
                .contentType(ContentType.JSON)
                .body(payload)

        .when()
                .patch("/api/users/2")

        .then()
                .statusCode(200);
    }
}

TestNG provides reporting and parallel execution support.

Common Challenges While Testing PATCH Requests

API testers often encounter several issues while testing PATCH endpoints.

Partial Update Validation

Ensure only specified fields are updated.

Incorrect Content Types

Some APIs require:

application/json-patch+json

instead of:

application/json

Authentication Failures

Expired or invalid tokens can cause unauthorized responses.

Inconsistent API Behavior

Some APIs incorrectly implement PATCH as PUT.

Serialization Issues

Improper payload serialization may break requests.

Best Practices for PATCH Request Testing

Following best practices improves reliability and maintainability.

Use Reusable Methods

Create helper methods for common operations.

Validate Both Positive and Negative Scenarios

Always test valid and invalid requests.

Use Environment Variables

Avoid hardcoding URLs and tokens.

Implement Logging

Logs simplify debugging.

Validate Response Time

Performance matters for APIs.

Example:

.then()
    .time(lessThan(3000L));

Use POJO Serialization

POJOs improve code organization.

Add Assertions for Data Integrity

Verify that non-updated fields remain unchanged.

Real-World PATCH Testing Scenario

Consider an e-commerce application where order status needs updating.

Example Payload

{
  "status": "Shipped"
}

REST Assured Test

@Test
public void updateOrderStatus() {

    String payload = "{ \"status\": \"Shipped\" }";

    given()
            .baseUri("https://api.shop.com")
            .header("Authorization", "Bearer token")
            .contentType(ContentType.JSON)
            .body(payload)

    .when()
            .patch("/orders/5001")

    .then()
            .statusCode(200)
            .body("status", equalTo("Shipped"));
}

This type of scenario is common in production-grade systems.

Difference Between PUT and PATCH Testing

FeaturePUTPATCH
UpdatesEntire resourcePartial resource
Payload SizeLargerSmaller
Risk of Data LossHigherLower
UsageFull replacementPartial modification
Testing FocusEntire object validationSelective field validation

Understanding this distinction is important during API automation.

Advanced Validation Techniques

Response Time Validation

.then()
    .time(lessThan(2000L));

Content Validation

.body("updatedAt", notNullValue());

Multiple Assertions

.then()
    .statusCode(200)
    .body("job", equalTo("Engineer"))
    .body("updatedAt", notNullValue());

Combining assertions increases test reliability.

Building a Robust API Automation Framework

PATCH request testing is usually part of a larger framework.

A scalable framework typically includes:

  • Base test classes
  • Utility methods
  • Request specifications
  • Response validators
  • Logging utilities
  • Data-driven testing
  • Reporting integration
  • CI/CD pipeline integration

REST Assured integrates well with:

  • Jenkins
  • Maven
  • Allure Reports
  • Extent Reports
  • GitHub Actions

This makes it ideal for enterprise API automation.

Conclusion

Testing PATCH requests using REST Assured in Java is an essential skill for modern API testers and automation engineers. Since PATCH operations are designed for partial updates, validating them carefully ensures APIs behave correctly without unintentionally modifying unrelated data.

REST Assured simplifies PATCH request testing through its expressive syntax, powerful validation capabilities, and seamless Java integration. From basic PATCH requests to advanced scenarios involving authentication, path parameters, schema validation, logging, and reusable frameworks, REST Assured provides everything needed for comprehensive API testing.

A successful PATCH testing strategy should include positive validation, negative testing, response verification, schema validation, performance checks, and authentication handling. Using best practices such as POJO serialization, reusable request specifications, proper assertions, and logging can significantly improve test reliability and maintainability.

In real-world enterprise applications, PATCH requests are heavily used for updating user profiles, order statuses, account settings, permissions, and many other partial modifications. Poorly tested PATCH endpoints can lead to data corruption, inconsistent application states, and serious production issues. Therefore, investing time in designing robust PATCH API tests is extremely valuable.

By mastering REST Assured PATCH request testing, QA engineers and developers can build scalable, maintainable, and highly reliable API automation frameworks that support continuous integration and modern agile development workflows.