[JAVA] Wenden Sie den Matching-Prozess für reguläre Ausdrücke mit JSON Sassert an

Es gibt eine Bibliothek namens JSONassert, die JSON in Java vergleicht. Beim Vergleich von JSON mit dieser Bibliothek werden diesmal jedoch normale Ausdrücke für die Wertübereinstimmung verwendet. Ich möchte kurz vorstellen, wie man es anwendet.

Überprüfungsversion

Verwenden Sie die standardmäßig unterstützte Methode

Verwenden Sie "CustomComparator", um das Element anzugeben, für das Sie den erwarteten Wert wie unten gezeigt als regulären Ausdruck behandeln möchten.

JSON muss überprüft werden


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

JSON, das den erwarteten Wert ausdrückt


{
  "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}"
  }
}

Das Folgende ist ein Beispiel für eine Spezifikation beim Vergleichen von "object.token" unter Verwendung eines regulären Ausdrucks.

Beispiel für einen Aufruf einer Vergleichsmethode


JSONAssert.assertEquals(expectedJson.toString(2), actualJson.toString(2),
    new CustomComparator(JSONCompareMode.STRICT,
        new Customization("object.token", new RegularExpressionValueMatcher<>()) //Übereinstimmung mit dem für den erwarteten Wert angegebenen Muster
    )
);

Sie können während der Überprüfung auch ein Muster angeben, wie unten gezeigt.

Beispiel für die Angabe eines Musters während der Überprüfung


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}")) //Abgleich mit dem hier angegebenen Muster ohne Verwendung des im Erwartungswert JSON beschriebenen Werts
    )
);

Ordnen Sie alle Elemente regulären Ausdrücken zu

In der Standardfunktion erfolgt die Anwendung regulärer Ausdrücke Element für Element (soweit ich weiß) (möglicherweise wird die Platzhalter-ähnliche Angabe von Pfaden unterstützt !?). Also ... Ich möchte meinen eigenen "JSONComparator" erstellen, der alle Elemente mit regulären Ausdrücken abgleichen kann, ohne "CustomComparator" zu verwenden.

Beispiel für die Erstellung von 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);
    //Nehmen Sie eine Methode an, um einmal mit einer exakten Übereinstimmung zu vergleichen und im Fall von NG auf die Übereinstimmung mit einem regulären Ausdruck zurückzugreifen
    //Da die meisten Elemente exakt abgeglichen werden können, können die Verarbeitungskosten im Vergleich zum bedingungslosen Abgleich durch reguläre Ausdrücke (sollte) reduziert werden.
    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) {
      //Container(Objekt + Array)Wenn es sich um ein Objekt handelt, übertragen Sie es in die Standardimplementierung
      super.compareValues(prefix, expectedValue, actualValue, result);
    } else {
      //Rufen Sie für Werte (Zeichenfolgen, Zahlen, Boolesche Werte) ValueMatcher mit Unterstützung für reguläre Ausdrücke auf, um sie zu vergleichen
      try {
        if (!matcher.equal(actualValue, expectedValue)) {
          //Fehlerbehandlung, wenn festgestellt wird, dass eine Nichtübereinstimmung vorliegt, wenn der reguläre Ausdruck nicht übereinstimmt
          result.fail(prefix, expectedValue, actualValue);
        }
      } catch (ValueMatcherException e) {
        //Fehlerbehandlung, wenn eine Nichtübereinstimmung durch Abgleich mit einem regulären Ausdruck festgestellt wird
        result.fail(prefix, e);
      }
    }
  }

}

Testfall zur Überprüfung erstellt

Als Referenz füge ich auch den Testfall ein, der zum Zeitpunkt der Überprüfung erstellt wurde.

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);
        }
      }
    }

  }

}

Zusammenfassung

Es gibt kein Problem nur mit der Standardfunktion, aber ich wollte eine Implementierung, die "alle Elemente mit regulären Ausdrücken abgleichen" ... - Der JSON, den Sie erwarten, wenn Sie den Antwort-BODY der Web-API überprüfen. Wird als Datei vorbereitet und um einen Mechanismus zu übernehmen, der die tatsächlichen Antwortdaten mit dem aus der Erwartungswertdatei gelesenen JSON vergleicht, verwenden Sie in jedem Testfall "CustomComparator", um das Zielelement auszuwählen. Ich dachte, es wäre (ein wenig) schwierig anzugeben, und ich wollte es automatisch anwenden können, indem ich einen regulären Ausdruck in der Erwartungswertdatei angab.

Referenzseite

Recommended Posts

Wenden Sie den Matching-Prozess für reguläre Ausdrücke mit JSON Sassert an
Anders als bei JSON
Grundlagen regulärer Ausdrücke
JS regulärer Ausdruck
Ruby regulärer Ausdruck
Maskieren Sie die durch Trennzeichen getrennte Benutzer-ID / das Kennwort mit einem kanonischen Ausdruck
Importieren Sie JSON mit SolrJ
Validierung von JSON mit JSON-Schema
Behandeln Sie JSON mit minimal-json
^, $ im regulären Ausdruck von Rails
Unicode-Beispiel für reguläre Ausdrücke
Regulärer Ausdruck für Passwort
Formatieren Sie JSON mit org.json
Zusammenfassung der regulären Ausdrücke von Java
Extrahieren Sie eine Zeichenkette, die mit einem Großbuchstaben (Ruby) in Großbuchstaben beginnt.