Learnitweb

Unit Testing JSON Responses with JsonAssert in Spring Boot

In this tutorial, we will explore how to write effective unit tests for REST controllers that return JSON responses. We will dive into using the JsonAssert library, which simplifies asserting JSON content by ignoring irrelevant differences such as spacing and order, and focusing only on the important fields.

Prerequisites

  • A Spring Boot project with the spring-boot-starter-test dependency included in your pom.xml.
  • Basic knowledge of JUnit and unit testing REST controllers.

spring-boot-starter-test brings in dependencies like JUnitMockitoHamcrest, and importantly, JsonAssert—which we’ll use extensively.

What is JsonAssert?

JsonAssert is a powerful tool for asserting JSON content easily in unit tests. It allows flexible matching:

  • Ignores extra spaces.
  • You can specify only the fields you want to assert, ignoring other fields.
  • Offers strict and non-strict modes for asserting JSON structure.

Understanding JsonAssert Under the Hood

When you use the .andExpect(content().json(expected)) method in Spring MockMvc tests:

  • It internally calls JsonAssert.assertEquals(expected, actual, strict) with strict set to false.
  • The actual JSON string comes from response.getContentAsString().
  • The expected JSON string is whatever you pass in.
  • strict = false means JsonAssert allows missing fields in the expected JSON and ignores order.

Basic Example

Let’s look at how to assert a JSON response using JsonAssert directly in a separate unit test spike class—independent of Spring MVC:

Step 1: Create a test class

package com.example.unit;

import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;

public class JsonAssertTest {

    @Test
    public void jsonAssertBasicTest() throws Exception {
        // Simulated JSON response from a service
        String actualResponse = "{ \"id\": 1, \"name\": \"Paul\", \"price\": 10, \"quantity\": 20 }";

        // Expected JSON to match against (only asserting id, name, and price)
        String expectedResponse = "{ \"id\": 1, \"name\": \"Paul\", \"price\": 10 }";

        // Perform the assertion ignoring extra fields (strict = false)
        JSONAssert.assertEquals(expectedResponse, actualResponse, false);
    }
}

Explanation:

  • The test passes, even though the actualResponse contains a quantity field missing from expectedResponse.
  • Because strict is false, JsonAssert ignores any fields not present in the expected JSON.

Strict vs Non-Strict Mode

  • strict=true : JSON must exactly match: all fields present, no extras. Spaces ignored.
  • strict=false : Only compare fields in expected JSON; extras in actual are ignored.

Example for strict mode:

@Test
public void jsonAssertStrictTest() throws Exception {
    String actualResponse = "{ \"id\": 1, \"name\": \"Paul\", \"price\": 10, \"quantity\": 20 }";
    String expectedResponse = "{ \"id\": 1, \"name\": \"Paul\", \"price\": 10 }";

    // This will fail because 'quantity' is missing from expected when strict=true
    JSONAssert.assertEquals(expectedResponse, actualResponse, true);
}

When to use which mode?

  • Use strict=false when you only care about validating some key fields.
  • Use strict=true when your exact JSON structure must match.

Handling Formatting and Escaping

  • JsonAssert ignores spaces and formatting differences.
  • You can write expected JSON without escape characters if values do not contain spaces or special characters.

Example:

String expected = "{ id:1, name:Paul, price:10 }";  // No quotes required around keys and simple values

If values contain spaces, escape with quotes:

String expected = "{ id:1, name:\"Paul Smith\", price:10 }";