Java >> Java tutorial >  >> Tag >> Json

Introduktion til JSONassert

1. Oversigt

I denne artikel vil vi se på JSONAssert-biblioteket – et bibliotek fokuseret på at forstå JSON-data og skrive komplekse JUnit-tests ved hjælp af disse data.

2. Maven Dependency

Lad os først tilføje Maven-afhængigheden:

<dependency>
    <groupId>org.skyscreamer</groupId>
    <artifactId>jsonassert</artifactId>
    <version>1.5.0</version>
</dependency>

Tjek venligst den seneste version af biblioteket her.

3. Arbejde med simple JSON-data

3.1. Brug af LENIENT Tilstand

Lad os starte vores test med en simpel JSON-strengsammenligning:

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

Testen vil bestå som den forventede JSON-streng, og den faktiske JSON-streng er den samme.

Sammenligningstilstanden LENIENT betyder, at selvom den faktiske JSON indeholder udvidede felter, vil testen stadig bestå:

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

Som vi kan se, er den rigtige variabel indeholder et ekstra felt zip som ikke er til stede i den forventede streng . Alligevel vil testen bestå.

Dette koncept er nyttigt i applikationsudviklingen. Det betyder, at vores API'er kan vokse og returnere yderligere felter efter behov uden at bryde de eksisterende tests.

3.2. Brug af STRICT Tilstand

Den adfærd, der er nævnt i det foregående underafsnit, kan nemt ændres ved at bruge STRICT sammenligningstilstand:

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

Bemærk venligst brugen af ​​assertNotEquals() i ovenstående eksempel.

3.3. Brug af en boolesk I stedet for JSONCompareMode

Sammenligningstilstanden kan også defineres ved at bruge en overbelastet metode, der tager boolesk i stedet for JSONCompareMode hvor LENIENT =falsk og STRICT =sand :

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. Den logiske sammenligning

Som beskrevet tidligere, JSONAssert foretager en logisk sammenligning af dataene. Dette betyder, at rækkefølgen af ​​elementer ikke betyder noget, mens du håndterer JSON-objekter:

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

Strenge eller ej, vil ovenstående test bestå i begge tilfælde.

Et andet eksempel på logisk sammenligning kan demonstreres ved at bruge forskellige typer for den samme værdi:

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

Den første ting at bemærke her er, at vi bruger JSONObject i stedet for en streng, som vi gjorde for tidligere eksempler. Den næste ting er, at vi har brugt Integer til forventet og Dobbelt for faktisk . Testen vil bestå uanset typerne, fordi den logiske værdi 12345 for dem begge er den samme.

Selv i det tilfælde, hvor vi har indlejret objektrepræsentation, fungerer dette bibliotek ret godt:

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. Påstande med brugerspecificerede meddelelser

Alle assertEquals() og assertNotEquals() metoder accepterer en streng besked som den første parameter. Denne meddelelse giver en vis tilpasning til vores testcases ved at give en meningsfuld meddelelse i tilfælde af testfejl:

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

I tilfælde af fejl, vil hele fejlmeddelelsen give mere mening:

Only one field is expected: name 
Unexpected: id

Den første linje er den brugerspecificerede meddelelse, og den anden linje er den yderligere meddelelse fra biblioteket.

4. Arbejde med JSON-arrays

Sammenligningsreglerne for JSON-arrays adskiller sig lidt sammenlignet med JSON-objekter.

4.1. Rækkefølgen af ​​elementerne i en matrix

Den første forskel er, at rækkefølgen af ​​elementer i en matrix skal være nøjagtig den samme i STRICT sammenligningstilstand . Men for LENIENT sammenligningstilstand, rækkefølgen er ligegyldig:

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

Dette er ret nyttigt i det scenarie, hvor API'en returnerer en række sorterede elementer, og vi ønsker at verificere, om svaret er sorteret.

4.2. De udvidede elementer i et array

En anden forskel er, at udvidede elementer ikke er tilladt, når der arbejdes med 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);

Ovenstående eksempel viser tydeligt, at selv med LENIENT sammenligningstilstand, skal emnerne i det forventede array matche emnerne i det rigtige array nøjagtigt. Tilføjelse eller fjernelse, selv et enkelt element, vil resultere i en fejl.

4.3. Matrixspecifikke operationer

Vi har også et par andre teknikker til at verificere indholdet af arrays yderligere.

Antag, at vi ønsker at verificere størrelsen af ​​arrayet. Dette kan opnås ved at bruge en konkret syntaks som forventet værdi:

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

strengen “{navne:[4]}” angiver den forventede størrelse af arrayet.

Lad os se på en anden sammenligningsteknik:

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

Ovenstående eksempel bekræfter, at alle elementer i arrayet skal have en værdi mellem [1,5], både 1 og 5 inklusive. Hvis der er en værdi mindre end 1 eller større end 5, vil ovenstående test mislykkes.

5. Eksempel på avanceret sammenligning

Overvej brugssituationen, hvor vores API returnerer flere id s, hvor hver enkelt er et heltal værdi. Det betyder, at alle id s kan verificeres ved hjælp af et simpelt regulært udtryk '\d '.

Ovenstående regex kan kombineres med en CustomComparator og anvendt på alle værdierne for alle id s. Hvis nogen af ​​id s ikke matcher regex, vil testen mislykkes:

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

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

"{id:x} ” i ovenstående eksempel er intet andet end en pladsholder – x kan erstattes af hvad som helst. Da det er stedet, hvor regex-mønsteret '\d ’ vil blive anvendt. Siden id selv er inde i et andet felt indgang , Tilpasning angiver placeringen af ​​id , så CustomComparator kan udføre sammenligningen.

6. Konklusion

I denne hurtige artikel har vi set på forskellige scenarier, hvor JSONAssert kan være nyttig. Vi startede med et super simpelt eksempel og gik over til mere komplekse sammenligninger.

Som altid kan den fulde kildekode for alle de eksempler, der diskuteres her, selvfølgelig findes på GitHub.


Java tag