WebTestClient 检查 jsonPath 是否包含子字符串
WebTestClient check that jsonPath contains sub string
在 MockMvc 中,可以断言 jsonPath 包含替代
.andExpect(jsonPath("$.error.message")
.value(containsString("message")))
我想知道是否有一种很好的方法可以为 WebTestClient 做同样的事情,语法有点不同
webClient.post().uri("/test")
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(MyRequest), MyRequest.class)
.exchange()
.expectStatus().isBadRequest()
.expectBody()
.jsonPath("$.message").isEqualTo("message")
但我只找到了与之相关的 isEqualTo 方法。
可以通过从 WebTestClient.BodyContentSpec 中提取 getBodyAsString() 来完成,但它看起来不太好。
目前(自 Spring Framework 5.0.4)不支持与 WebTestClient
一起使用的 Hamcrest 匹配器。
但是,您可以使用正则表达式来测试 JsonPath 是否存在,其中元素 包含 给定的子字符串。
例如,我刚刚在Spring自己的测试套件中验证了以下内容。请注意 /persons
URL returns 人员对象列表(即 new Person("Jane"), new Person("Jason"), new Person("John")
)并且 Person
class 有一个 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();
因此,对于您的用例,我假设以下可能有效:
.jsonPath("$[?(@.error.message =~ /.*substring.*/)].error.message").hasJsonPath()
另一种选择是使用 consumeWith(...)
而不是 jsonPath(...)
,然后直接使用 Spring 的 JsonPathExpectationsHelper
(MockMvc
在内部使用).
请告诉我什么对你有用。
p.s。 SPR-16574 可能会解决 Spring 5.x.
中的这个缺点
查看以下示例以了解如何使用 WebTestClient 执行其余 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();
WebTestClient WebFlux Spring 启动 2.3.4:
wtc.post()
.uri(CREATE_ACCOUNT_URL)
.contentType(APP_MEDIA_TYPE)
.accept(APP_MEDIA_TYPE)
.bodyValue(json)
.exchange()
.expectStatus().isBadRequest()
.expectBody()
.consumeWith(this::dumpToScreen)
.jsonPath("$.timestamp").isNotEmpty()
.jsonPath("$.path").isEqualTo(CREATE_ACCOUNT_URL)
.jsonPath("$.status").isEqualTo(HttpStatus.BAD_REQUEST.value())
.jsonPath("$.error").isEqualTo(HttpStatus.BAD_REQUEST.getReasonPhrase())
.jsonPath("$.message").isEqualTo(WebExchangeBindingException.MESSAGE)
.jsonPath("$.reason").exists()
.jsonPath("$.reason.size()").isEqualTo(2)
.jsonPath("$.reason.password.size()").isEqualTo(1)
.jsonPath("$.reason.password").isEqualTo(EXC_MSG_NOT_NULL)
.jsonPath("$.reason.email.size()").isEqualTo(1)
.jsonPath("$.reason.email").isEqualTo(EXC_MSG_NOT_NULL);
// When having more than 1 message
//.jsonPath("$.reason.email").value(containsInAnyOrder(EXC_MSG_NOT_NULL, EXC_MSG_NOT_BLANK));
在 MockMvc 中,可以断言 jsonPath 包含替代
.andExpect(jsonPath("$.error.message")
.value(containsString("message")))
我想知道是否有一种很好的方法可以为 WebTestClient 做同样的事情,语法有点不同
webClient.post().uri("/test")
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(MyRequest), MyRequest.class)
.exchange()
.expectStatus().isBadRequest()
.expectBody()
.jsonPath("$.message").isEqualTo("message")
但我只找到了与之相关的 isEqualTo 方法。
可以通过从 WebTestClient.BodyContentSpec 中提取 getBodyAsString() 来完成,但它看起来不太好。
目前(自 Spring Framework 5.0.4)不支持与 WebTestClient
一起使用的 Hamcrest 匹配器。
但是,您可以使用正则表达式来测试 JsonPath 是否存在,其中元素 包含 给定的子字符串。
例如,我刚刚在Spring自己的测试套件中验证了以下内容。请注意 /persons
URL returns 人员对象列表(即 new Person("Jane"), new Person("Jason"), new Person("John")
)并且 Person
class 有一个 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();
因此,对于您的用例,我假设以下可能有效:
.jsonPath("$[?(@.error.message =~ /.*substring.*/)].error.message").hasJsonPath()
另一种选择是使用 consumeWith(...)
而不是 jsonPath(...)
,然后直接使用 Spring 的 JsonPathExpectationsHelper
(MockMvc
在内部使用).
请告诉我什么对你有用。
p.s。 SPR-16574 可能会解决 Spring 5.x.
中的这个缺点查看以下示例以了解如何使用 WebTestClient 执行其余 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();
WebTestClient WebFlux Spring 启动 2.3.4:
wtc.post()
.uri(CREATE_ACCOUNT_URL)
.contentType(APP_MEDIA_TYPE)
.accept(APP_MEDIA_TYPE)
.bodyValue(json)
.exchange()
.expectStatus().isBadRequest()
.expectBody()
.consumeWith(this::dumpToScreen)
.jsonPath("$.timestamp").isNotEmpty()
.jsonPath("$.path").isEqualTo(CREATE_ACCOUNT_URL)
.jsonPath("$.status").isEqualTo(HttpStatus.BAD_REQUEST.value())
.jsonPath("$.error").isEqualTo(HttpStatus.BAD_REQUEST.getReasonPhrase())
.jsonPath("$.message").isEqualTo(WebExchangeBindingException.MESSAGE)
.jsonPath("$.reason").exists()
.jsonPath("$.reason.size()").isEqualTo(2)
.jsonPath("$.reason.password.size()").isEqualTo(1)
.jsonPath("$.reason.password").isEqualTo(EXC_MSG_NOT_NULL)
.jsonPath("$.reason.email.size()").isEqualTo(1)
.jsonPath("$.reason.email").isEqualTo(EXC_MSG_NOT_NULL);
// When having more than 1 message
//.jsonPath("$.reason.email").value(containsInAnyOrder(EXC_MSG_NOT_NULL, EXC_MSG_NOT_BLANK));