Introduction à JSONassert

Introduction à JSONassert

1. Vue d'ensemble

Dans cet article, nous allons examiner lesJSONAssert library - une bibliothèque axée sur la compréhension des données JSON et l'écriture de testsJUnit complexes à l'aide de ces données.

2. Dépendance Maven

Tout d'abord, ajoutons la dépendance Maven:


    org.skyscreamer
    jsonassert
    1.5.0

Veuillez consulter la dernière version de la bibliothèquehere.

3. Travailler avec des données JSON simples

3.1. Utilisation du modeLENIENT

Commençons nos tests par une simple comparaison de chaînes JSON:

String actual = "{id:123, name:\"John\"}";
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, JSONCompareMode.LENIENT);

Le test passera comme la chaîne JSON attendue et la chaîne JSON réelle est la même.

La comparaisonmode LENIENT means that even if the actual JSON contains extended fields, the test will still pass:

String actual = "{id:123, name:\"John\", zip:\"33025\"}";
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, JSONCompareMode.LENIENT);

Comme on peut le voir, la variablereal contient un champ supplémentairezip qui n'est pas présent dans lesString attendus. Pourtant, le test va passer.

Ce concept est utile dans le développement d'applications. Cela signifie que nos API peuvent se développer et renvoyer des champs supplémentaires si nécessaire sans interrompre les tests existants.

3.2. Utilisation du modeSTRICT

Le comportement mentionné dans la sous-section précédente peut être facilement modifié en utilisant le mode de comparaisonSTRICT:

String actual = "{id:123,name:\"John\"}";
JSONAssert.assertNotEquals(
  "{name:\"John\"}", actual, JSONCompareMode.STRICT);

Veuillez noter l'utilisation deassertNotEquals() dans l'exemple ci-dessus.

3.3. Utiliser unBoolean au lieu deJSONCompareMode

Le mode de comparaison peut également être défini en utilisant une méthode surchargée qui prendboolean au lieu deJSONCompareModeLENIENT = false etSTRICT = true:

String actual = "{id:123,name:\"John\",zip:\"33025\"}";
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, JSONCompareMode.LENIENT);
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, false);

actual = "{id:123,name:\"John\"}";
JSONAssert.assertNotEquals(
  "{name:\"John\"}", actual, JSONCompareMode.STRICT);
JSONAssert.assertNotEquals(
  "{name:\"John\"}", actual, true);

3.4. La comparaison logique

Comme décrit précédemment,JSONAssert effectue une comparaison logique des données. Cela signifie que l'ordre des éléments n'a pas d'importance lorsqu'il s'agit d'objets JSON:

String result = "{id:1,name:\"John\"}";
JSONAssert.assertEquals(
  "{name:\"John\",id:1}", result, JSONCompareMode.STRICT);
JSONAssert.assertEquals(
  "{name:\"John\",id:1}", result, JSONCompareMode.LENIENT);

Strict ou non, le test ci-dessus passera dans les deux cas.

Un autre exemple de comparaison logique peut être démontré en utilisant différents types pour la même valeur:

JSONObject expected = new JSONObject();
JSONObject actual = new JSONObject();
expected.put("id", Integer.valueOf(12345));
actual.put("id", Double.valueOf(12345));

JSONAssert.assertEquals(expected, actual, JSONCompareMode.LENIENT);

La première chose à noter ici est que nous utilisonsJSONObject au lieu d'une chaîne comme nous l'avons fait pour les exemples précédents. Ensuite, nous avons utiliséInteger pourexpected etDouble pouractual. Le test réussira quels que soient les types car la valeur logique 12345 est la même pour les deux.

Même dans le cas où nous avons une représentation d'objet imbriquée, cette bibliothèque fonctionne plutôt bien:

String result = "{id:1,name:\"Juergen\",
  address:{city:\"Hollywood\", state:\"LA\", zip:91601}}";
JSONAssert.assertEquals("{id:1,name:\"Juergen\",
  address:{city:\"Hollywood\", state:\"LA\", zip:91601}}", result, false);

3.5. Assertions avec messages spécifiés par l'utilisateur

Toutes les méthodesassertEquals() etassertNotEquals() acceptent un messageString comme premier paramètre. Ce message fournit une certaine personnalisation à nos cas de test en fournissant un message significatif en cas d'échec de test:

String actual = "{id:123,name:\"John\"}";
String failureMessage = "Only one field is expected: name";
try {
    JSONAssert.assertEquals(failureMessage,
      "{name:\"John\"}", actual, JSONCompareMode.STRICT);
} catch (AssertionError ae) {
    assertThat(ae.getMessage()).containsIgnoringCase(failureMessage);
}

En cas d’échec, l’ensemble du message d’erreur aura plus de sens:

Only one field is expected: name
Unexpected: id

La première ligne est le message spécifié par l'utilisateur et la deuxième ligne est le message supplémentaire fourni par la bibliothèque.

4. Utilisation des tableaux JSON

Les règles de comparaison des tableaux JSON diffèrent quelque peu de celles des objets JSON.

4.1. L'ordre des éléments dans un tableau

La première différence est quethe order of elements in an array has to be exactly same in STRICT comparison mode. Cependant, pour le mode de comparaison deLENIENT, l'ordre n'a pas d'importance:

String result = "[Alex, Barbera, Charlie, Xavier]";
JSONAssert.assertEquals(
  "[Charlie, Alex, Xavier, Barbera]", result, JSONCompareMode.LENIENT);
JSONAssert.assertEquals(
  "[Alex, Barbera, Charlie, Xavier]", result, JSONCompareMode.STRICT);
JSONAssert.assertNotEquals(
  "[Charlie, Alex, Xavier, Barbera]", result, JSONCompareMode.STRICT);

Ceci est très utile dans le scénario où l'API renvoie un tableau d'éléments triés et nous voulons vérifier si la réponse est triée.

4.2. Les éléments étendus dans un tableau

Une autre différence est queextended elements are not allowed when the dealing with JSON arrays:

String result = "[1,2,3,4,5]";
JSONAssert.assertEquals(
  "[1,2,3,4,5]", result, JSONCompareMode.LENIENT);
JSONAssert.assertNotEquals(
  "[1,2,3]", result, JSONCompareMode.LENIENT);
JSONAssert.assertNotEquals(
  "[1,2,3,4,5,6]", result, JSONCompareMode.LENIENT);

L'exemple ci-dessus démontre clairement que même avec le mode de comparaisonLENIENT, les éléments du tableau attendu doivent correspondre exactement aux éléments du tableau réel. L'ajout ou la suppression, même d'un seul élément, entraînera un échec.

4.3. Opérations spécifiques à la baie

Nous avons également recours à deux autres techniques pour vérifier davantage le contenu des tableaux.

Supposons que nous voulions vérifier la taille du tableau. Ceci peut être réalisé en utilisant une syntaxe concrète comme valeur attendue:

String names = "{names:[Alex, Barbera, Charlie, Xavier]}";
JSONAssert.assertEquals(
  "{names:[4]}",
  names,
  new ArraySizeComparator(JSONCompareMode.LENIENT));

LeString“\{names:[4]}” spécifie la taille attendue du tableau.

Jetons un œil à une autre technique de comparaison:

String ratings = "{ratings:[3.2,3.5,4.1,5,1]}";
JSONAssert.assertEquals(
  "{ratings:[1,5]}",
  ratings,
  new ArraySizeComparator(JSONCompareMode.LENIENT));

L'exemple ci-dessus vérifie que tous les éléments du tableau doivent avoir une valeur comprise entre [1,5], 1 et 5 inclus. S'il existe une valeur inférieure à 1 ou supérieure à 5, le test ci-dessus échouera.

5. Exemple de comparaison avancée

Considérez le cas d'utilisation où notre API renvoie plusieursids, chacun étant une valeurInteger. Cela signifie que tous lesids peuvent être vérifiés à l'aide d'une simple expression régulière «\d».

L'expression régulière ci-dessus peut être combinée avec unCustomComparator et appliquée à toutes les valeurs de tous lesids. Si l'un desids ne correspond pas à l'expression régulière, le test échouera:

JSONAssert.assertEquals("{entry:{id:x}}", "{entry:{id:1, id:2}}",
  new CustomComparator(
  JSONCompareMode.STRICT,
  new Customization("entry.id",
  new RegularExpressionValueMatcher("\\d"))));

JSONAssert.assertNotEquals("{entry:{id:x}}", "{entry:{id:1, id:as}}",
  new CustomComparator(JSONCompareMode.STRICT,
  new Customization("entry.id",
  new RegularExpressionValueMatcher("\\d"))));


Le «\{id:x}» dans l'exemple ci-dessus n'est rien d'autre qu'un espace réservé - lesx peuvent être remplacés par n'importe quoi. Car c’est l’endroit où le modèle de regex ‘\d’ sera appliqué. Puisque leid lui-même est à l'intérieur d'un autre champentry, leCustomization spécifie la position desid, de sorte que leCustomComparator puisse effectuer la comparaison.

6. Conclusion

Dans cet article rapide, nous avons examiné divers scénarios dans lesquels JSONAssert peut être utile. Nous avons commencé avec un exemple très simple et nous sommes passés à des comparaisons plus complexes.

Bien sûr, comme toujours, le code source complet de tous les exemples discutés ici peut être trouvéover on GitHub.