0

在 Spring Boot 2.4.2WebTestClient中,我在集成测试中使用调用请求。

这是获取消息列表的第一个请求:

webTestClient
    .get()
    .uri("/api/messages")
    .headers(http -> http.setBearerAuth(token))
    .exchange()
    .expectStatus().isOk()
    .expectHeader().contentType(APPLICATION_JSON)
    .expectBody()
    .jsonPath("$.length()").isEqualTo(1)
    .jsonPath("$[0].id").isNumber()
    .jsonPath("$[0].type").isEqualTo(4);

现在我想调用一个后续请求来下载特定消息。为此,我需要id已经用jsonPath("$[0].id").

webTestClient
    .get()
    .uri(uriBuilder -> uriBuilder.path("/api/messages/{id}").build(extractedId))
    .headers(http -> http.setBearerAuth(token))
    .exchange()
    .expectStatus().isOk();

如何将其提取id到局部变量中,以便它可用于第二个请求?

4

2 回答 2

2

你可以查看他们的官方文档

但是稍微扩展一下答案,最简单的方法就是这样

val result = webTestClient
                .get()
                .uri(uriBuilder -> uriBuilder.path("/api/messages/{id}").build(extractedId))
                .headers(http -> http.setBearerAuth(token))
                .exchange()
                .expectStatus().isOk()
                .returnResult();

还有一些方法可以获得文档中解释的(无限)响应流,这与上面的示例非常相似。

于 2021-06-18T09:49:59.623 回答
1

我遇到了同样的问题,这是我想出的解决方案。

根据文件,

WebTestClient 是围绕 WebClient 的一个瘦壳,​​使用它来执行请求并公开一个专用的、流畅的 API 来验证响应。

据我了解,它适用于以与断言类似的方式测试响应assertThat

在我的解决方案中,我改为使用WebClient提取值。

下面的代码片段应该解释所有细节。请注意,这只是一个通用示例,您应该根据需要对其进行定制。

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

import static org.springframework.http.MediaType.APPLICATION_JSON;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FooTest {

    @Autowired
    private WebTestClient webTestClient;

    /**
     * The port of the server. It starts on a RANDOM_PORT. @LocalServerPort is a way to find out what this port is.
     */
    @LocalServerPort
    private int port;

    @Test
    void someTestMethod() throws JSONException {


        // Create the request body that we'll send with the POST request.
        String postRequestBody = new JSONObject()
                .put("JsonField_1", "value a")
                .put("JsonFiled_2", "value b")
                // .put("any_additional_json_fields", "with_any_values")
                .toString();

        // The URI where we'll send the request to.
        String postRequestUri = "http://localhost:" + String.valueOf(port) + "/some_api";

        // Send a POST request, and save the response.
        TypeOfResponseWeExpect response = WebClient.create()
                .post()
                .uri(postRequestUri)
                .contentType(APPLICATION_JSON)
                .accept(APPLICATION_JSON)
                .body(BodyInserters.fromValue(postRequestBody))
                .retrieve()
                .bodyToMono(TypeOfResponseWeExpect.class)
                .block();

        // And now we can extract any values from the response.
        long extractedId = response.getId();
        String token = response.getToken();
        FooField fooField = response.getFoo();
        BarField barField = response.getBar();

        // Now we can use the extracted id field, or any field from the response.
        webTestClient
                .get()
                .uri(uriBuilder -> uriBuilder.path("/api/messages/{id}").build(extractedId))
                .headers(http -> http.setBearerAuth(token))
                .exchange()
                .expectStatus().isOk();
    }
}

编辑:经过进一步尝试,我也找到了一种使用 WebTestClient 提取响应的方法:

TypeOfResponseWeExpect response = this.webTestClient
        .post()
        .uri(postRequestUri)
        .contentType(APPLICATION_JSON)
        .accept(APPLICATION_JSON)
        .body(BodyInserters.fromValue(postRequestBody))
        .exchange()
        .expectBody(TypeOfResponseWeExpect.class)
        .returnResult()
        .getResponseBody();
于 2021-09-23T15:50:42.197 回答