Testing arbitrary Json arrays

We recently had a request from a client as to how they could improve their testing of a web service. Prior to each release, they would run a series of tests against the candidate service which were structured as unit tests for ease of running.

The web service would return a Json document representing a simple unordered array of complex objects (each with their own schema) and the expected behaviour was to check that the values hadn’t changed. The only commonality in schema was a key property which should be used for choosing what to compare against what.

Initially, they were doing this via checking the raw text which was returned. When they were different, they had some interesting times understanding where the differences were.

Within the testing framework, we have a method for comparing sets of objects; and within the object flattening framework, we have support for processing Json objects (note that they were already using so the example uses the same for consistency in their code base).

These can be combined together to perform their comparisons and to get full visibility of all of the differences between the objects.

The interesting part of the code is the following.

// expected = IEnumerable of expected values
// actual = IEnumerable of actual values
var results = setComparer.CompareObjectSets<Newtonsoft.Json.Linq.JToken>((idx, jobject) =>
	// We define the keys for comparison as extracting the proeprty on the underlying Json object called 'key'
	var keys = new Dictionary<string, object>();

	if (jobject is Newtonsoft.Json.Linq.JObject jo)
		keys["key"] = jo.Property("key").Value;
	return keys;

The full code can be seen on GitHub here.

Note that in this specific example, the returned Json was a simple array of the objects and therefore the deserialization could be done as a JArray. If the objects to be compared were nested in the schema, then a custom object (using object[] for the objects to be compared) could be used for the deserialization.

This simple snippet allowed them to simplify their investigations in the case of any differences, thus saving them time on each release.