Spring 5 中文解析測試篇-WebTestClient

3.7 WebTestClient

WebTestClient是圍繞WebClient的薄殼,可用於執行請求並公開專用的流利API來驗證響應。 WebTestClient經過使用模擬請求和響應綁定到WebFlux應用程序,或者它能夠經過HTTP鏈接測試任何Web服務器。html

Kotlin用戶:請參閱本節WebTestClient的使用有關。java

3.7.1 安裝

要建立WebTestClient,必須選擇多個服務器設置選項之一。實際上,你是在配置WebFlux應用程序以綁定到該URL,仍是使用URL鏈接到正在運行的服務器。react

綁定到控制器git

如下示例顯示如何建立服務器設置以一次測試一個@Controllergithub

client = WebTestClient.bindToController(new TestController()).build();

前面的示例加載WebFlux Java配置並註冊給定的控制器。使用模擬請求和響應對象,能夠在沒有HTTP服務器的狀況下測試生成的WebFlux應用程序。構建器上有更多方法能夠定製默認WebFlux Java配置。web

綁定到路由器功能spring

如下示例顯示瞭如何經過RouterFunction設置服務器:編程

RouterFunction<?> route = ...
client = WebTestClient.bindToRouterFunction(route).build();

在內部,配置被傳遞到RouterFunctions.toWebHandler。使用模擬請求和響應對象,能夠在沒有HTTP服務器的狀況下測試生成的WebFlux應用程序。json

綁定到ApplicationContextapi

如下示例顯示瞭如何經過應用程序或其部分子集的Spring配置來設置服務器:

@SpringJUnitConfig(WebConfig.class) //1
class MyTests {

    WebTestClient client;

    @BeforeEach
    void setUp(ApplicationContext context) {  //2
        client = WebTestClient.bindToApplicationContext(context).build(); //3
    }
}
  1. 指定要加載的配置
  2. 注入配置
  3. 建立WebTestClient

在內部,配置被傳遞到WebHttpHandlerBuilder以創建請求處理鏈。有關更多詳細信息,請參見WebHandler API。使用模擬請求和響應對象,能夠在沒有HTTP服務器的狀況下測試生成的WebFlux應用程序。

綁定到服務器

如下服務器設置選項使你能夠鏈接到正在運行的服務器:

client = WebTestClient.bindToServer().baseUrl("http://localhost:8080").build();

客戶端構建者

除了前面介紹的服務器設置選項以外,你還能夠配置客戶端選項、包括基本URL、默認標頭,客戶端過濾器等。這些選項在bindToServer以後很容易得到。對於全部其餘服務器,你須要使用configureClient()從服務器配置過渡到客戶端配置,以下所示:

client = WebTestClient.bindToController(new TestController())
        .configureClient()
        .baseUrl("/test")
        .build();
3.7.2 寫測試

WebTestClient提供了與WebClient相同的API,直到使用exchange()執行請求爲止。 exchange()以後是連接的API工做流,用於驗證響應。

一般,首先聲明響應狀態和標頭,以下所示:

client.get().uri("/persons/1")
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .expectStatus().isOk()
            .expectHeader().contentType(MediaType.APPLICATION_JSON)

而後,你指定如何解碼和使用響應主體:

  • ExpectBody(Class <T>):解碼爲單個對象。
  • ExpectBodyList(Class <T>):解碼並將對象收集到List <T>
  • ExpectBody():解碼爲byte []以獲取JSON內容或一個空的正文。

而後,你能夠爲主體使用內置的斷言。如下示例顯示了一種方法:

client.get().uri("/persons")
        .exchange()
        .expectStatus().isOk()
        .expectBodyList(Person.class).hasSize(3).contains(person);

你還能夠超越內置的斷言並建立本身的斷言,如如下示例所示:

import org.springframework.test.web.reactive.server.expectBody

client.get().uri("/persons/1")
        .exchange()
        .expectStatus().isOk()
        .expectBody(Person.class)
        .consumeWith(result -> {
            // custom assertions (e.g. AssertJ)...
        });

你還能夠退出工做流程並得到結果,以下所示:

EntityExchangeResult<Person> result = client.get().uri("/persons/1")
        .exchange()
        .expectStatus().isOk()
        .expectBody(Person.class)
        .returnResult();

當你須要使用泛型解碼爲目標類型時,請尋找接受ParameterizedTypeReference而不是Class <T>的重載方法。

無內容

若是響應沒有內容(或者你不在意),請使用Void.class,以確保釋放資源。如下示例顯示瞭如何執行此操做:

client.get().uri("/persons/123")
        .exchange()
        .expectStatus().isNotFound()
        .expectBody(Void.class);

或者,若是要斷言沒有響應內容,則能夠使用相似於如下內容的代碼:

client.post().uri("/persons")
        .body(personMono, Person.class)
        .exchange()
        .expectStatus().isCreated()
        .expectBody().isEmpty();

JSON內容

當你使用ExpectBody()時,響應以byte[]的形式使用。這對於原始內容聲明頗有用。例如,你能夠使用JSONAssert來驗證JSON內容,以下所示:

client.get().uri("/persons/1")
        .exchange()
        .expectStatus().isOk()
        .expectBody()
        .json("{\"name\":\"Jane\"}")

你還能夠使用JSONPath表達式,以下所示:

client.get().uri("/persons")
        .exchange()
        .expectStatus().isOk()
        .expectBody()
        .jsonPath("$[0].name").isEqualTo("Jane")
        .jsonPath("$[1].name").isEqualTo("Jason");

流式響應

要測試無限流(例如,「 text/event-stream」或「 application/stream + json」),你須要在響應狀態和響應頭斷言以後當即退出連接的API(經過使用returnResult),以下所示示例顯示:

FluxExchangeResult<MyEvent> result = client.get().uri("/events")
        .accept(TEXT_EVENT_STREAM)
        .exchange()
        .expectStatus().isOk()
        .returnResult(MyEvent.class);

如今,你能夠使用Flux <T>,在到達解碼對象時對其進行斷言,而後在達到測試目標時在某個時候取消。咱們建議使用反應堆測試模塊中的StepVerifier進行此操做,如如下示例所示:

Flux<Event> eventFlux = result.getResponseBody();

StepVerifier.create(eventFlux)
        .expectNext(person)
        .expectNextCount(4)
        .consumeNextWith(p -> ...)
        .thenCancel()
        .verify();

請求體

當涉及到構建請求時,WebTestClient提供了與WebClient相同的API,實現主要是簡單的傳遞。請參閱WebClient文檔,以獲取有關如何使用正文準備請求的示例,包括提交表單數據,多部分請求等。

做者

我的從事金融行業,就任過易極付、思建科技、某網約車平臺等重慶一流技術團隊,目前就任於某銀行負責統一支付系統建設。自身對金融行業有強烈的愛好。同時也實踐大數據、數據存儲、自動化集成和部署、分佈式微服務、響應式編程、人工智能等領域。同時也熱衷於技術分享創立公衆號和博客站點對知識體系進行分享。關注公衆號:青年IT男 獲取最新技術文章推送!

博客地址: http://youngitman.tech

CSDN: https://blog.csdn.net/liyong1028826685

微信公衆號:

技術交流羣:

相關文章
相關標籤/搜索