WebTestClient 检查 jsonPath 是否包含子字符串

Evg*_*gen 2 java spring-test reactive

在 MockMvc 中,可以断言 jsonPath 包含 substing

.andExpect(jsonPath("$.error.message")
.value(containsString("message")))
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一个很好的方法可以为 WebTestClient 做同样的事情,语法有点不同

webClient.post().uri("/test")
                .contentType(MediaType.APPLICATION_JSON)
                .body(Mono.just(MyRequest), MyRequest.class)
                .exchange()
                .expectStatus().isBadRequest()
                .expectBody()
                .jsonPath("$.message").isEqualTo("message")
Run Code Online (Sandbox Code Playgroud)

但我发现只有与它相关的 isEqualTo 方法。

它可以通过从 WebTestClient.BodyContentSpec 中提取 getBodyAsString() 来完成,但它看起来不太好。

Sam*_*nen 6

目前(从 Spring Framework 5.0.4 开始)不支持 Hamcrest 匹配器与WebTestClient.

但是,您可以使用正则表达式来测试 JsonPath 是否存在,其中元素包含给定的子字符串。

例如,我刚刚在 Spring 自己的测试套件中验证了以下内容。请注意,该/personsURL 返回一个人员对象列表(即new Person("Jane"), new Person("Jason"), new Person("John")),并且Person该类具有一个name属性。

this.client.get().uri("/persons")
        .accept(MediaType.APPLICATION_JSON_UTF8)
        .exchange()
        .expectStatus().isOk()
        .expectBody()
        // The following determines if at least one person is returned with a
        // name containing "oh", and "John" matches that.
        .jsonPath("$[?(@.name =~ /.*oh.*/)].name").hasJsonPath();
Run Code Online (Sandbox Code Playgroud)

因此,对于您的用例,我认为以下可能有效:

.jsonPath("$[?(@.error.message =~ /.*substring.*/)].error.message").hasJsonPath()

另一种选择是使用consumeWith(...)而不是jsonPath(...)然后JsonPathExpectationsHelper直接使用 Spring 的(这是MockMvc内部使用的)。

请让我知道什么对你有用。

ps SPR-16574可能会在 Spring 5.x 中解决这个缺点。


mak*_*son 6

查看以下示例,了解如何使用 WebTestClient 执行 REST API 测试:

testClient.post().uri(URL,"value")
            .header("Authorization", "Basic " + Base64Utils
                    .encodeToString((loginInner + ":" + passwordInner).getBytes(UTF_8)))
            .exchange()
            .expectStatus()
            .isEqualTo(HttpStatus.BAD_REQUEST)
            .expectBody()
            .jsonPath("$.value_A").isEqualTo("100")
            .jsonPath("$.value_B").isEqualTo("some text")
            .jsonPath("$.value_C").isNotEmpty();
Run Code Online (Sandbox Code Playgroud)


Vit*_*ura 5

从 Spring Framework 5(不确定是哪个版本)开始,可以使用以下内容:

.jsonPath("message")
                .value(Matchers.containsString(<your_string>));
Run Code Online (Sandbox Code Playgroud)