[JAVA] Appliquer le processus de correspondance d'expressions régulières avec JSON Sassert

Il existe une bibliothèque appelée JSONassert qui compare JSON en Java, mais cette fois, lors de la comparaison de JSON avec cette bibliothèque, des expressions normales sont utilisées pour la correspondance de valeurs. Je voudrais brièvement présenter comment l'appliquer.

Version de vérification

Utilisez la méthode standard prise en charge

Utilisez CustomComparator pour spécifier l'élément pour lequel vous souhaitez traiter la valeur attendue comme une expression régulière, comme indiqué ci-dessous.

JSON à vérifier


{
  "array": [
    1,
    2
  ],
  "id": 100,
  "type": "foo",
  "object": {
    "name": "Kazuki",
    "token": "ac648657-797e-49f7-9563-150c9b5c2284"
  }
}

JSON qui exprime la valeur attendue


{
  "array": [
    1,
    2
  ],
  "id": 100,
  "type": "foo",
  "object": {
    "name": "Kazuki",
    "token": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
  }
}

Voici un exemple de spécification lors de la comparaison de ʻobject.token` à l'aide d'une expression régulière.

Exemple d'appel de méthode de comparaison


JSONAssert.assertEquals(expectedJson.toString(2), actualJson.toString(2),
    new CustomComparator(JSONCompareMode.STRICT,
        new Customization("object.token", new RegularExpressionValueMatcher<>()) //Correspondance en utilisant le modèle spécifié pour la valeur attendue
    )
);

Vous pouvez également spécifier un modèle lors de la vérification, comme indiqué ci-dessous.

Exemple de spécification d'un modèle lors de la vérification


JSONAssert.assertEquals(expectedJson.toString(2), actualJson.toString(2),
    new CustomComparator(JSONCompareMode.STRICT,
        new Customization("object.token", new RegularExpressionValueMatcher<>("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")) //Correspondance à l'aide du modèle spécifié ici sans utiliser la valeur décrite dans la valeur attendue JSON
    )
);

Faire correspondre tous les éléments avec des expressions régulières

Dans la fonctionnalité standard, l'application d'expressions régulières est élément par élément (pour autant que je sache) (peut-être qu'il existe un support pour la spécification de chemins de type générique!?). Donc ... je voudrais créer mon propre JSONComparator qui peut correspondre à tous les éléments en utilisant des expressions régulières sans utiliser CustomComparator.

Exemple de création de JSONComparator


public class RegularExpressionComparator extends DefaultComparator {

  private static final RegularExpressionValueMatcher<Object> REGEX_VALUE_MATCHER = new RegularExpressionValueMatcher<>();

  private final ValueMatcher<Object> matcher;

  public RegularExpressionComparator(JSONCompareMode mode) {
    super(mode);
    //Adopter une méthode de comparaison une fois avec une correspondance exacte, et dans le cas de NG, revenir à une correspondance avec une expression régulière
    //Étant donné que la plupart des éléments peuvent être mis en correspondance exactement, le coût de traitement peut être réduit par rapport à la correspondance inconditionnelle par expression régulière (devrait).
    this.matcher = (actual, expected) -> Objects.equals(actual, expected) ||
        expected instanceof String && REGEX_VALUE_MATCHER.equal(actual, expected);
  }

  @Override
  public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
    if (actualValue instanceof JSONArray || actualValue instanceof JSONObject) {
      //récipient(Objet + tableau)S'il s'agit d'un objet, transférez-le dans l'implémentation par défaut
      super.compareValues(prefix, expectedValue, actualValue, result);
    } else {
      //Pour les valeurs (chaînes, nombres, booléens), appelez ValueMatcher avec prise en charge des expressions régulières pour comparer
      try {
        if (!matcher.equal(actualValue, expectedValue)) {
          //Gestion des erreurs lorsqu'il est jugé qu'il y a une discordance quand il n'est pas mis en correspondance par l'expression régulière
          result.fail(prefix, expectedValue, actualValue);
        }
      } catch (ValueMatcherException e) {
        //Gestion des erreurs lorsqu'une discordance est déterminée par correspondance avec une expression régulière
        result.fail(prefix, e);
      }
    }
  }

}

Cas de test créé pour la vérification

Pour référence, je vais également coller le cas de test créé au moment de la vérification.

package com.example.assertdemo;

import java.util.Objects;
import java.util.UUID;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;
import org.skyscreamer.jsonassert.RegularExpressionValueMatcher;
import org.skyscreamer.jsonassert.ValueMatcher;
import org.skyscreamer.jsonassert.ValueMatcherException;
import org.skyscreamer.jsonassert.comparator.DefaultComparator;

public class JSONAssertRegexTests {

  @Test
  public void regexAssert() throws JSONException {

    JSONObject expectedJson = new JSONObject();
    {
      JSONArray array = new JSONArray();
      array.put(1);
      array.put(2);
      JSONObject object = new JSONObject();
      object.put("name", "Kazuki");
      object.put("token", "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
      expectedJson.put("id", 100);
      expectedJson.put("type", "foo");
      expectedJson.put("array", array);
      expectedJson.put("object", object);
      System.out.println("-----expectedJson------");
      System.out.println(expectedJson.toString(2));
    }

    JSONObject actualJson = new JSONObject();
    {
      JSONArray array = new JSONArray();
      array.put(1);
      array.put(2);
      actualJson.put("id", 100);
      actualJson.put("array", array);
      JSONObject object = new JSONObject();
      object.put("name", "Kazuki");
      object.put("token", UUID.randomUUID().toString());
      actualJson.put("id", 100);
      actualJson.put("type", "foo");
      actualJson.put("array", array);
      actualJson.put("object", object);
      System.out.println("-----actualJson------");
      System.out.println(actualJson.toString(2));
    }

    JSONAssert.assertEquals(expectedJson.toString(2),
        actualJson.toString(2),
        new RegularExpressionComparator(JSONCompareMode.STRICT));

  }

  public static class RegularExpressionComparator extends DefaultComparator {

    private static final RegularExpressionValueMatcher<Object> REGEX_VALUE_MATCHER = new RegularExpressionValueMatcher<>();

    private final ValueMatcher<Object> matcher;

    public RegularExpressionComparator(JSONCompareMode mode) {
      super(mode);
      this.matcher = (actual, expected) -> Objects.equals(actual, expected) ||
          expected instanceof String && REGEX_VALUE_MATCHER.equal(actual, expected);
    }

    @Override
    public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
      if (actualValue instanceof JSONArray || actualValue instanceof JSONObject) {
        super.compareValues(prefix, expectedValue, actualValue, result);
      } else {
        try {
          if (!matcher.equal(actualValue, expectedValue)) {
            result.fail(prefix, expectedValue, actualValue);
          }
        } catch (ValueMatcherException e) {
          result.fail(prefix, e);
        }
      }
    }

  }

}

Résumé

Il n'y a pas de problème avec juste la fonction standard, mais je voulais une implémentation qui "correspond à tous les éléments avec des expressions régulières" ...- Le JSON que vous attendez lors de la vérification du CORPS de réponse de l'API Web. Est préparé sous forme de fichier, et afin d'adopter un mécanisme qui compare les données de réponse réelles avec le JSON lu à partir du fichier de valeurs attendues, utilisez CustomComparator dans chaque cas de test pour sélectionner l'élément cible. Je pensais que ce serait (un peu) difficile à spécifier, et je voulais pouvoir l'appliquer automatiquement en spécifiant une expression régulière dans le fichier de valeur attendue.

Site de référence

Recommended Posts

Appliquer le processus de correspondance d'expressions régulières avec JSON Sassert
Différé avec JSON
Bases des expressions régulières
Expression régulière JS
Expression régulière Ruby
Masquez le mot de passe de l'ID utilisateur / mot de passe délimité par une expression canonique
Importer JSON avec SolrJ
Validation de JSON avec le schéma JSON
Gérez JSON avec minimal-json
^, $ dans l'expression régulière Rails
exemple d'expression régulière unicode
Expression régulière pour le mot de passe
Formater JSON avec org.json
résumé des expressions régulières java
Extraire une chaîne de caractères commençant par une majuscule avec une expression régulière (Ruby)