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

मैं यह सुनिश्चित करना चाहता हूं कि कोई अन्य सदस्य उत्पन्न जोंस में मौजूद न हों। उम्मीद है कि उन्हें jsonPath का उपयोग करके गिना जाएगा। क्या यह संभव है? वैकल्पिक समाधानों का भी स्वागत है।

जवाबों:


233

सरणी के आकार का परीक्षण करने के लिए :jsonPath("$", hasSize(4))

ऑब्जेक्ट के सदस्यों की गणना करने के लिए :jsonPath("$.*", hasSize(4))


यानी परीक्षण करने के लिए कि एपीआई 4 आइटमों की एक सरणी लौटाता है :

स्वीकृत मूल्य: [1,2,3,4]

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

यह जांचने के लिए कि एपीआई में 2 सदस्यों वाली एक वस्तु है :

स्वीकृत मूल्य: {"foo": "oof", "bar": "rab"}

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

मैं Hamcrest संस्करण 1.3 और स्प्रिंग टेस्ट 3.2.5 का उपयोग कर रहा हूं। कृपया ध्यान दें

hasSize (int) javadoc

नोट: आपको हैमरेस्ट-लाइब्रेरी निर्भरता और import static org.hamcrest.Matchers.*;काम करने के लिए hasSize () को शामिल करने की आवश्यकता है।


2
@mattb - अगर मावेन का उपयोग करते हैं, तो hamcrest-allएक निर्भरता के रूप में न जोड़ें , लेकिन उपयोग करें hamcrest-library: code.google.com/p/hamcrest/wiki/ HamcrestDistributables
एडम मिशालिक

1
क्या होगा अगर कोई आकार नहीं जानता है और इसे प्राप्त करना चाहता है?
जिग्मंटस

2
@ मेनुका-ईशान - मुझे नहीं लगता कि इसके अनुसार वंचित है: MockMvcResultMatchers.jsonPath () javadoc
lopisan

@zygimantus आपको अपनी ऑब्जेक्ट / एरे पर सभी फ़ील्ड का आकार गिनना चाहिए, या तो स्रोत कोड या प्रतिक्रिया के वेब ब्राउज़र डेवलपर टूल निरीक्षण से।
21

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 Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.