đếm thành viên với jsonpath?


103

Có thể đếm số lượng thành viên bằng JsonPath không?

Sử dụng kiểm tra mvc mùa xuân, tôi đang kiểm tra một bộ điều khiển tạo ra

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

với

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

Tôi muốn đảm bảo rằng không có thành viên nào khác có mặt trong json đã tạo. Hy vọng rằng bằng cách sử dụng jsonPath đếm chúng. Nó có khả thi không? Các giải pháp thay thế cũng được hoan nghênh.

Câu trả lời:


233

Để kiểm tra kích thước của mảng :jsonPath("$", hasSize(4))

Để đếm các thành viên của đối tượng :jsonPath("$.*", hasSize(4))


Tức là để kiểm tra API đó trả về một mảng gồm 4 mục:

giá trị được chấp nhận: [1,2,3,4]

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

để kiểm tra API đó trả về một đối tượng chứa 2 thành viên:

giá trị được chấp nhận: {"foo": "oof", "bar": "rab"}

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

Tôi đang sử dụng Hamcrest phiên bản 1.3 và Spring Test 3.2.5.

hasSize (int) javadoc

Lưu ý: Bạn cần bao gồm sự phụ thuộc vào thư viện import static org.hamcrest.Matchers.*;hamcrest và để hasSize () hoạt động.


2
@mattb - nếu sử dụng Maven, không thêm hamcrest-alllàm phụ thuộc mà hãy sử dụng hamcrest-library: code.google.com/p/hamcrest/wiki/HamcrestDistributables
Adam Michalik

1
Điều gì sẽ xảy ra nếu một người không biết kích thước và muốn lấy nó?
zygimantus

2
@ menuka-ishan - Tôi không nghĩ nó không còn được dùng nữa, theo: MockMvcResultMatchers.jsonPath () javadoc
lopisan

@zygimantus, bạn phải đếm kích thước của tất cả các trường trên Đối tượng / Mảng của mình, từ mã nguồn hoặc công cụ của nhà phát triển trình duyệt web kiểm tra phản hồi.
cellepo 12/09/19

12

Bạn cũng có thể sử dụng các phương thức bên trong jsonpath, vì vậy thay vì

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

bạn có thể làm

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

7

Chúng ta có thể sử dụng các hàm JsonPath như size()hoặc length(), như sau:

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

Hoặc chỉ cần phân tích cú pháp net.minidev.json.JSONObjectvà nhận kích thước:

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

Thật vậy, cách tiếp cận thứ hai có vẻ hoạt động tốt hơn cách tiếp cận đầu tiên. Tôi đã thực hiện kiểm tra hiệu suất JMH và nhận được kết quả sau:

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

Mã ví dụ có thể được tìm thấy ở đây .


4

Hôm nay tôi đã tự giải quyết việc này. Có vẻ như điều này không được thực hiện trong các xác nhận có sẵn. Tuy nhiên, có một phương thức để truyền vào một org.hamcrest.Matcherđối tượng. Với điều đó, bạn có thể làm điều gì đó như sau:

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

nếu bạn không có com.jayway.jsonassert.JsonAsserttrên classpath của mình (đó là trường hợp của tôi), thử nghiệm theo cách sau có thể là một giải pháp khả thi:

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

[lưu ý: tôi đã giả định rằng nội dung của json luôn là một mảng]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.