Core Java

Assert Collection of JSON Objects Ignoring Order Example

1. Introduction

JavaScript Object Notation (JSON) is a text-based format for storing and transporting data. In this example, I will demonstrate JSON array equality ignore order with both Jackson and JsonAssert libraries with the following steps:

  • Parse the JSON array into a collection of objects ( JsonNode or List of JSONObject).
  • Sort the collection.
  • Assert each individual object via JsonAssert or assert with Arrays.equals method.

2. Setup

In this step, I will create a maven project with jsonassert, jackson-databind, and Junit5 libraries.

pom.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.zheng.demo</groupId>
    <artifactId>assertJsonCollection</artifactId>
    <version>0.0.1-SNAPSHOT</version>
 
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>17</release>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.11.3</version>
            <scope>test</scope>
        </dependency>
 
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.11.3</version>
            <scope>test</scope>
        </dependency>
 
        <!--
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.18.1</version>
        </dependency>
 
        <dependency>
            <groupId>org.skyscreamer</groupId>
            <artifactId>jsonassert</artifactId>
            <version>1.5.3</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

3. Test JSON Data

In this step, I will create a TestJsonData.java class that includes several JSON strings. Please note that the actualJsonArray and expectedJsonArray have the same collection of objects. The only difference is the JSON element’s order.

TestJsonData.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package org.zheng.demo.assertJsonCollection;
 
public class TestJsonData {
 
    protected String maryJson = "{\"id\":1,\"name\":\"Mary\"}";
 
    protected String terryJson = "{\"id\":2,\"name\":\"Terry\"}";  
    protected String terryJsonInDiffOrder = "{ \"name\":\"Terry\",\"id\":2}";
 
    protected String actualJsonArray = "[" + maryJson + "," + terryJson + "]";
    protected String expectedJsonArray = "[" + terryJsonInDiffOrder + "," + maryJson + "]";
 
 
    public TestJsonData() {
        super();
    }
 
}
  • Line 7 and 8: The terryJson and terryJsonInDiffOrder JSON Object strings have the same content but the elements are ordered differently.
  • Line 10 and 11: the actualJsonArray and expectedJsonArray JSON Array strings have the same content but the elements are ordered differently.

4. JSON Array Equality Ignore Order

4.1 JSON Array Equality Ignore Order via Jackson

In this step, I will create a TestAssertJsonCollectionWithJackson.java that extends from TestJsonData and includes two tests: test_readValue_JsonNode and test_readValue_listMap.

  • test_readValue_JsonNode – parse the JSON string as a JsonNode[], then assert the sorted array via java.util.Arrays.equals and java.util.Arrays.deepEquals methods.
  • test_readValue_listMap – parse the JSON string as List<Map>, then assert sorted lists via org.junit.jupiter.api.Assertions.assertEquals method.

TestAssertJsonCollectionWithJackson.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package org.zheng.demo.assertJsonCollection;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
 
import org.junit.jupiter.api.Test;
 
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class TestAssertJsonCollectionWithJackson extends TestJsonData {
 
    ObjectMapper ob = new ObjectMapper();
 
    private JsonNode[] readJsonNodes(final String jsonArray) {
        JsonNode[] jsonNodeList = null;
        try {
            jsonNodeList = ob.readValue(jsonArray, JsonNode[].class);
 
        } catch (JsonProcessingException e) {
 
            e.printStackTrace();
        }
 
        return jsonNodeList;
    }
 
    @Test
    void test_readValue_JsonNode() {
        // parse JSON into Jackson'sJsonNode
        JsonNode[] actualJsonNodes = readJsonNodes(actualJsonArray);
        JsonNode[] expectedJsonNodes = readJsonNodes(expectedJsonArray);
 
        // sort the JsonNode array
        Arrays.sort(actualJsonNodes, Comparator.comparingInt(jNode -> jNode.get("id").asInt()));
        Arrays.sort(expectedJsonNodes, Comparator.comparingInt(jNode -> jNode.get("id").asInt()));
 
        // compare the JsonNode array without any order
        assertTrue(Arrays.equals(actualJsonNodes, expectedJsonNodes));
        assertTrue(Arrays.deepEquals(actualJsonNodes, expectedJsonNodes));
 
    }
 
    @Test
    void test_readValue_listMap() throws JsonMappingException, JsonProcessingException {
        List<Map<String, Object>> actualListMap = ob.readValue(actualJsonArray,
                new TypeReference<List<Map<String, Object>>>() {
                });
 
        List<Map<String, Object>> expectedListMap = ob.readValue(expectedJsonArray,
                new TypeReference<List<Map<String, Object>>>() {
                });
 
        List<Map<String, Object>> sortedExpected = expectedListMap.stream()
                .sorted(Comparator.comparing(map -> (Integer) map.get("id"))).toList();
 
        assertEquals(actualListMap, sortedExpected);
 
    }
 
}
  • Line 39, 40: parse the JSON string as JsonNode array for both actualJsonArray and expectedJsonArray are defined in step 3.
  • Line 43, 44: sort the JsonNode array with Arrays.sort method.
  • Line 47, 48: assert the JsonNode array with Arrays.equals and Arrays.deepEquals methods.
  • Line 54, 58: parse the JSON string as List of Map for actualJsonArray and expectedJsonArray are defined in step 3.
  • Line 62: sort the expectedListMap based on the id field.
  • Line 65: assert a collection of JSON actualListMap and sortedExpected are equal.

4.2 JSON Array Equality Ignore Order via JsonAssert

In this step, I will create a TestAssertJsonCollectionWithJsonAssert.java test class that asserts a collection of JSON objects ignoring order via JsonAssert.

TestAssertJsonCollectionWithJsonAssert.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package org.zheng.demo.assertJsonCollection;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
 
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
 
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
 
public class TestAssertJsonCollectionWithJsonAssert extends TestJsonData {
 
    private List<JSONObject> jsonArrayToSortedList(final JSONArray jsonArray) throws JSONException {
        List<JSONObject> sortedList = new ArrayList<>();
 
        for (int i = 0; i < jsonArray.length(); i++) {
            sortedList.add(jsonArray.getJSONObject(i));
        }
 
        sortedList.sort(Comparator.comparingInt(o -> {
            try {
                return o.getInt("id");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return 0;
        }));
 
        return sortedList;
    }
 
    @Test
    void test_jsonassert_JSONObject() throws Exception {
        JSONArray actualArray = new JSONArray(actualJsonArray);
        JSONArray expectedArray = new JSONArray(expectedJsonArray);
 
        List<JSONObject> actualSortedList = jsonArrayToSortedList(actualArray);
        List<JSONObject> expectedSortedList = jsonArrayToSortedList(expectedArray);
 
        assertEquals(actualSortedList.size(), expectedSortedList.size());
 
        for (int i = 0; i < expectedSortedList.size(); i++) {
            JSONAssert.assertEquals(expectedSortedList.get(i).toString(), actualSortedList.get(i).toString(), true);
        }
    }
 
}
  • Line 38, 39: create JSONArray from the JSON string variable.
  • Line 41, 42: convert the JSONArray into a sorted list of JSONObjects.
  • Line 46, 47: assert each JSONObject equality within the list.

5. Run Tests

Run the Junit and capture the output as Figure 1.

json array equality ignore order tests
Figure 1. Junit Test Results

6. Conclusion

In this example, I created two test classes that assert a collection of JSON objects ignoring order with both Jackson and JsonAssert libraries. Both libraries require parsing the JSON into either an array or a list of Java objects first and then comparing the sorted array or lists.

7. Download

This was an example of a maven project that asserted a collection of JSON objects ignoring order.

Download
You can download the full source code of this example here: Assert Collection of JSON Objects Ignoring Order Example

Mary Zheng

Mary graduated from the Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She worked as a lead Software Engineer where she led and worked with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button