jsonpath ile üye saymak?


103

JsonPath kullanarak üye sayısını saymak mümkün mü?

Spring mvc testini kullanarak , üreten bir denetleyiciyi test ediyorum

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

ile

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

Oluşturulan json'da başka hiçbir üyenin bulunmadığından emin olmak istiyorum. Umarım jsonPath kullanarak bunları sayarak. Mümkün mü? Alternatif çözümlere de açığız.

Yanıtlar:


233

Dizinin boyutunu test etmek için :jsonPath("$", hasSize(4))

Nesnenin üyelerini saymak için :jsonPath("$.*", hasSize(4))


Örneğin, API'nin 4 öğeden oluşan bir dizi döndürdüğünü test etmek için :

kabul edilen değer: [1,2,3,4]

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

API'nin 2 üye içeren bir nesne döndürdüğünü test etmek için :

kabul edilen değer: {"foo": "oof", "bar": "rab"}

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

Hamcrest sürüm 1.3 ve Spring Test 3.2.5 kullanıyorum.

hasSize (int) javadoc

Not: Hamcrest-library bağımlılığını dahil etmeniz ve import static org.hamcrest.Matchers.*;hasSize () için çalışmanız gerekir.


2
@mattb - Maven kullanıyorsanız, hamcrest-allbağımlılık olarak eklemeyin , ancak şunu kullanın hamcrest-library: code.google.com/p/hamcrest/wiki/HamcrestDistributables
Adam Michalik

1
Ya insan bedenini bilmiyor ve onu almak istiyorsa?
zygimantus

2
@ menuka-ishan - Ben göre, kaldırılmış sanmıyorum: MockMvcResultMatchers.jsonPath () javadoc
lopisan

@zygimantus, ya kaynak kodundan ya da yanıtın web tarayıcısı geliştirici araçları incelemesinden, Nesne / Dizinizdeki tüm alanların boyutunu hesaplamalısınız.
cellepo

12

Ayrıca jsonpath içindeki yöntemleri de kullanabilirsiniz, bu nedenle

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

yapabilirsin

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

7

JsonPath işlevlerini aşağıdaki gibi size()veya şu şekilde kullanabiliriz 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);
}

Veya basitçe ayrıştırıp net.minidev.json.JSONObjectboyutu elde edin:

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

Aslında, ikinci yaklaşım birincisinden daha iyi performans gösteriyor gibi görünüyor. JMH performans testi yaptım ve aşağıdaki sonuçları alıyorum:

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

Örnek kod burada bulunabilir .


4

Bugün bununla kendim ilgileniyorum. Mevcut iddialarda bu uygulanmış gibi görünmüyor. Bununla birlikte, bir org.hamcrest.Matchernesneye geçmek için bir yöntem vardır . Bununla aşağıdaki gibi bir şey yapabilirsiniz:

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.JsonAssertsınıf yolunuzda yoksa (benim için geçerliydi ), aşağıdaki şekilde test etmek olası bir geçici çözüm olabilir:

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

[not: json içeriğinin her zaman bir dizi olduğunu varsaydım]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.