wake-up-neo.com

mitglieder mit jsonpath zählen?

Kann man die Anzahl der Mitglieder, die JsonPath verwenden, zählen?

Verwendung von spring mvc test Ich teste einen Controller, der generiert 

{"foo": "oof", "bar": "rab"}

mit

standaloneSetup(new FooController(fooService)).build()
            .perform(get("/something").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
            .andExpect(jsonPath("$.foo").value("oof"))
            .andExpect(jsonPath("$.bar").value("rab"));

Ich möchte sicherstellen, dass keine anderen Mitglieder im generierten Json anwesend sind. Hoffentlich durch Zählen mit JsonPath. Ist es möglich? Alternative Lösungen sind ebenfalls willkommen.

77
NA.

So testen Sie die Größe von array: jsonPath("$", hasSize(4)) 

Mitglieder von object zählen: jsonPath("$.*", hasSize(4)) 


Das heißt Um diese API zu testen, wird ein array von 4 Elementen zurückgegeben:

zulässiger Wert: [1,2,3,4]

mockMvc.perform(get(API_URL))
       .andExpect(jsonPath("$", hasSize(4)));

zum Testen dieser API wird ein object zurückgegeben, das 2 Mitglieder enthält:

zulässiger Wert: {"foo": "oof", "bar": "rab"}

mockMvc.perform(get(API_URL))
       .andExpect(jsonPath("$.*", hasSize(2)));

Ich verwende Hamcrest Version 1.3 und Spring Test 3.2.5.RELEASE

hasSize (int) javadoc

Anmerkung: Sie müssen die Abhängigkeit von hamcrest-library und import static org.hamcrest.Matchers.*; angeben, damit hasSize () funktioniert.

169
lopisan

Ich habe mich heute damit beschäftigt. Es scheint nicht so, als wäre dies in den verfügbaren Behauptungen implementiert. Es gibt jedoch eine Methode zum Übergeben eines org.hamcrest.Matcher-Objekts. Damit kann man so etwas machen:

final int count = 4; // expected count

jsonPath("$").value(new BaseMatcher() {
    @Override
    public boolean matches(Object obj) {
        return obj instanceof JSONObject && ((JSONObject) obj).size() == count;
    }

    @Override
    public void describeTo(Description description) {
        // nothing for now
    }
})
4
Ben

Wir können JsonPath-Funktionen wie size() oder length() wie folgt verwenden:

  @Test
  public void givenJson_whenGetLengthWithJsonPath_thenGetLength() {
    String jsonString = "{'username':'jhon.user','email':'[email protected]','age':'28'}";

    int length = JsonPath
        .parse(jsonString)
        .read("$.length()");

    assertThat(length).isEqualTo(3);
  }

oder einfach nach net.minidev.json.JSONObject analysieren und de size erhalten:

  @Test
  public void givenJson_whenParseObject_thenGetSize() {
    String jsonString = "{'username':'jhon.user','email':'[email protected]','age':'28'}";

    JSONObject jsonObject = (JSONObject) JSONValue.parse(jsonString);

    assertThat(jsonObject)
        .size()
        .isEqualTo(3);
  }

In der Tat scheint der zweite Ansatz besser zu sein als der erste. Ich habe einen JMH-Leistungstest durchgeführt und erhalte folgende Ergebnisse:

| Benchmark                                       | Mode  | Cnt | Score       | Error        | Units |
|-------------------------------------------------|-------|-----|-------------|--------------|-------|
| JsonPathBenchmark.benchmarkJSONObjectParse      | thrpt | 5   | 3241471.044 | ±1718855.506 | ops/s |
| JsonPathBenchmark.benchmarkJsonPathObjectLength | thrpt | 5   | 1680492.243 | ±132492.697  | ops/s |

Den Beispielcode finden Sie hier .

2
SHoko

wenn Sie com.jayway.jsonassert.JsonAssert nicht in Ihrem Klassenpfad haben (was bei mir der Fall war), kann das Testen auf folgende Weise eine mögliche Problemumgehung sein:

assertEquals(expectedLength, ((net.minidev.json.JSONArray)parsedContent.read("$")).size());

[Anmerkung: Ich habe angenommen, dass der Inhalt des Json immer ein Array ist]

0
Tanvir

Sie können auch die Methoden im jsonpath verwenden, also statt 

mockMvc.perform(get(API_URL))
   .andExpect(jsonPath("$.*", hasSize(2)));

du kannst tun

mockMvc.perform(get(API_URL))
   .andExpect(jsonPath("$.length()", is(2)));
0
stalet