Guide to JSONassert (with Examples)

Learn to write test result assertions using the JSONassert with easy-to-understand examples. We can use this tutorial as JSONassert cookbook for quick reference.

1. Setting Up JSONassert

Using JSONassert with JUnit is very easy. We need to import its latest dependency from the Maven repo.

<dependency>
    <groupId>org.skyscreamer</groupId>
    <artifactId>jsonassert</artifactId>
    <version>1.5.1</version>
    <scope>test</scope>
</dependency>

All its classes, interfaces and methods come from the package org.skyscreamer.jsonassert. Now we can write all assertions using JUNIT assert methods:

JSONAssert.assertEquals(expectedJSON, actualJSON, strictMode);
JSONAssert.assertNotEquals(expectedJSON, actualJSON, strictMode);

2. Working with JSONassert

When writing tests for REST APIs with JUnit, comparing JSON fields can be achieved easily with a few libraries such as JsonPath. But if we want to compare the complete JSON response against a predefined JSON string then there is no direct support.

JSONassert, intelligently, converts the provided string into a JSON object and compares the logical structure and data with the JSON response object. We can directly pass a org.json.JSONObject or org.json.JSONArray instance in place of a String.

2.1. Comparison Modes

In JSON comparison, there are two things that we should consider: extended fields and field order. The extended fields mean that the actual response contains more fields than the comparison string.

JSONassert has inbuilt support for the following modes while comparing the JSON:

  • JSONCompareMode.STRICT : Extended fields are not allowed. Field ordering must match.
  • JSONCompareMode.LENIENT : Extended fields are allowed. Field ordering can differ.
  • JSONCompareMode.NON_EXTENSIBLE : Extended fields are not allowed. Field ordering can differ.
  • JSONCompareMode.STRICT_ORDER : Extended fields are allowed. Field ordering must match.

By default, JSONassert uses a lenient mode that ignores the ordering of JSON fields and allows extended fields. The recommendation is to use the LENIENT mode, always. It helps during the development phase when new fields are being added occasionally.

As a best practice, we should turn on the strict mode only if we need to enforce a particular order for arrays, or if we want to ensure that the actual JSON does not have any fields beyond what’s expected.

To change the comparison mode, use appropiate mode constant as the last argument in assertEquals() or assertNotEquals() methods.

JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.LENIENT); 
JSONAssert.assertNotEquals(expectedJSON, actualJSON, JSONCompareMode.STRICT); 

We can also pass the boolean parameter as the last argument which translates as follows:

  • false : JSONCompareMode.LENIENT
  • true : JSONCompareMode.STRICT
JSONAssert.assertEquals(expectedJSON, actualJSON, false); 

2.2. A Simple Example

Consider the following JSON string.

{
  "widget": {
    "debug": "on",
    "window": {
      "title": "Client Info",
      "name": "test widget"
    }
  }
}

If we have to write assertions to verify the JSON data using JSONPath, we need to write multiple statements as follows:

Assertions.assertEquals("on", JsonPath.read(json, "$.widget.debug"));
Assertions.assertEquals("Client Info", JsonPath.read(json, "$.widget.window.title"));
Assertions.assertEquals("test widget", JsonPath.read(json, "$.widget.window.name"));
...
...

But using the JSONassert, we can verify the whole JSON in a single statement. Note that the order of the fields does not change the assertion result.

JSONAssert.assertEquals(
  "{"widget":{"debug":"on","window":{"title":"Client Info","name":"test widget  "}}}", json, JSONCompareMode.LENIENT);

3. Using JSONObject and JSONArray

We can use JSONObject and JSONArray instances in place of JSON strings.

@testJSONObject
void testJSONObject(){
  JSONObject jsonObject = new JSONObject();
  jsonObject.put("widget", Map.of("debug", "on"));

  JSONAssert.assertEquals(
      "{"padding":[10,10,10,50]}", jsonObject, JSONCompareMode.LENIENT);
}

Similarly, we can test with JSONArray.

@Test
void testJSONArray(){
  JSONArray jsonArray = new JSONArray();
  jsonArray.put(10);
  jsonArray.put(10);
  jsonArray.put(10);
  jsonArray.put(50);

  JSONAssert.assertEquals(
      "[10,10,10,50]", jsonArray, JSONCompareMode.STRICT);
}

4. Comparison Failure Messages

Although JSONassert library provides useful messages, by default, we can supply any custom user-defined message as the first argument of assertEquals() and assertNotEquals() methods.

In case of a failed comparison, we will get the custom message as well as the library-provided message for the point of failure.

@Test
void testFailMessage(){
  String message = "Comparison Failed.";
  JSONAssert.assertEquals(message,
      "{\"widget\":{\"debug\":\"on\",\"window\":{\"titles\":\"Client Info\"," +
          "\"name\":\"client_info\"}}}", json, JSONCompareMode.LENIENT);
}

In the above example, we have changed the string title to titles. Check out the test output. It clearly tells that test was expecting titles inside the widget.window node but it couldn’t find it.

java.lang.AssertionError: Comparison Failed. widget.window
Expected: titles
but none found

5. Conclusion

In this JSONassert tutorial, we learned the basics of JSONassert library, setting it up with Maven and its different comparison modes. We also learned to compare JSON as strings or JSONObject instances with examples. Finally, we learned to configure and understand the user-defined messages in case of unsuccessful comparisons.

Happy Learning !!

Sourcecode on Github

Comments

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.