рахувати членів з jsonpath?


103

Чи можливо підрахувати кількість учасників, які використовують JsonPath?

Використовуючи весняний тест mvc, я тестую контролер, який генерує

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

з

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

Я хотів би переконатися, що в створеному json немає інших членів. Сподіваємось, підрахувавши їх за допомогою jsonPath. Це можливо? Альтернативні рішення також вітаються.

Відповіді:


233

Щоб перевірити розмір масиву :jsonPath("$", hasSize(4))

Для підрахунку членів об’єкта :jsonPath("$.*", hasSize(4))


Тобто для перевірки того, що API повертає масив із 4 елементів:

прийняте значення: [1,2,3,4]

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

перевірити, чи API повертає об'єкт, що містить 2 учасника:

прийняте значення: {"foo": "oof", "bar": "rab"}

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

Я використовую Hamcrest версії 1.3 та Spring Test 3.2.5.RELEASE

hasSize (int) javadoc

Примітка. Вам потрібно включити залежність бібліотеки import static org.hamcrest.Matchers.*;hamcrest і для роботи hasSize ().


2
@mattb - якщо ви користуєтеся Maven, не додайте її hamcrest-allяк залежність, а використовуйте hamcrest-library: code.google.com/p/hamcrest/wiki/HamcrestDistributables
Адам Міхалік

1
Що робити, якщо людина не знає розмір і хоче його отримати?
зигімантус

2
@ menuka-ishan - Я не думаю, що це застаріло, згідно з: MockMvcResultMatchers.jsonPath () javadoc
lopisan

@zygimantus ви повинні підрахувати розмір усіх полів на Object / Array, або з вихідного коду, або з перевірки відповіді інструментів для розробників веб-браузера.
cellepo

12

Ви також можете використовувати методи всередині jsonpath, тому замість

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

Ви можете зробити

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

7

Ми можемо використовувати функції JsonPath як size()або length(), як це:

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

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

    assertThat(length).isEqualTo(3);
}

Або просто проаналізуйте net.minidev.json.JSONObjectта отримайте розмір:

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

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

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

Дійсно, другий підхід виглядає краще, ніж перший. Я зробив тест працездатності JMH і отримую такі результати:

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

Приклад коду можна знайти тут .


4

Сьогодні я сам із цим займався. Здається, це не реалізовано в доступних твердженнях. Однак існує спосіб передачі в org.hamcrest.Matcherоб’єкт. З цим ви можете зробити щось на кшталт наступного:

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

0

якщо у вас немає com.jayway.jsonassert.JsonAssertна вашому класі (як це було у мене), можливе тестування наступним чином:

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

[Примітка: я припускав, що вміст json завжди є масивом]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.