Skip to content

Add a method to RestTestClient API that provides a JsonContentAssert #35624

@donalmurtagh

Description

@donalmurtagh

The RestTestClient API provides a .json(String expected) method that allows the entire JSON response to be verified via JSONAssert e.g.

restTestClient.get().uri("/persons/1")
            .exchange()
            .expectStatus().isOk()
            .expectBody()
            .json("""
                {
                  "data": [
                    {"id": "123", "name": "John Doe",  "email": "[email protected]"}
                  ]
                }
            """)

This approach is fine when verifying simple JSON responses, but it becomes unwieldy for more complex JSON responses and/or when we want to compare the JSON properties with Java object properties.

By contrast, the MockMvcTester API provides a bodyJson() method that returns a org.springframework.test.json.JsonContentAssert object that supports more fine-grained assertions, e.g.

mockMvcTester.get().uri("/persons/1")
            .assertThat()
            .hasStatusOk()
            .bodyJson()
            .extractingPath("$.data")
            .asArray().singleElement()
            .hasFieldOrPropertyWithValue("id", expectedUser.getId())
            .hasFieldOrPropertyWithValue("name", expectedUser.getName())
            .hasFieldOrPropertyWithValue("email", expectedUser.getEmail())

Proposal

Add a method toRestTestClient.BodyContentSpec that allows the response to be consumed with a JsonContentAssert, e.g.

restTestClient.get().uri("/persons/1")
            .exchange()
            .expectStatus().isOk()
            .expectBody() 
            .consumeWithJsonAssert((JsonContentAssert jsonContentAssert) -> {
                jsonContentAssert.extractingPath("$.data")
                        .asArray().singleElement()
                        .hasFieldOrPropertyWithValue("id", expectedUser.getId())
                        .hasFieldOrPropertyWithValue("name", expectedUser.getName())
                        .hasFieldOrPropertyWithValue("email", expectedUser.getEmail())
            })

Current Workaround

In the absence of this method, I create the JsonContentAssert as below:

restTestClient.get().uri("/persons/1")
    .exchange()
    .expectStatus().isOk()
    .expectBody()
    .consumeWith(response -> {
        String responseBody = new String(response.getResponseBody(), Charset.defaultCharset());
        JsonContentAssert jsonContentAssert = new JsonContent(responseBody).assertThat();
        jsonContentAssert.extractingPath("$.data")
                .asArray().singleElement()
                .hasFieldOrPropertyWithValue("id", expectedUser.getId())
                .hasFieldOrPropertyWithValue("name", expectedUser.getName())
                .hasFieldOrPropertyWithValue("email", expectedUser.getEmail())
    });

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions