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.
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
)
);
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);
}
}
}
}
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);
}
}
}
}
}
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.
Recommended Posts