非同步請求
本節介紹如何單獨使用 MockMvc 來測試非同步請求處理。如果透過 WebTestClient 使用 MockMvc,則無需進行任何特殊操作即可使非同步請求生效,因為 WebTestClient
會自動執行本節所述的操作。
Servlet 非同步請求,在 Spring MVC 中支援,其工作原理是退出 Servlet 容器執行緒,允許應用非同步計算響應,之後進行非同步分派以在 Servlet 容器執行緒上完成處理。
在 Spring MVC Test 中,可以透過先斷言生成的非同步值,然後手動執行非同步分派,最後驗證響應來測試非同步請求。下面是返回 DeferredResult
、Callable
或 Reactor Mono
等響應式型別的 Controller 方法的測試示例
-
Java
-
Kotlin
// static import of MockMvcRequestBuilders.* and MockMvcResultMatchers.*
@Test
void test() throws Exception {
MvcResult mvcResult = this.mockMvc.perform(get("/path"))
.andExpect(status().isOk()) (1)
.andExpect(request().asyncStarted()) (2)
.andExpect(request().asyncResult("body")) (3)
.andReturn();
this.mockMvc.perform(asyncDispatch(mvcResult)) (4)
.andExpect(status().isOk()) (5)
.andExpect(content().string("body"));
}
1 | 檢查響應狀態是否未改變 |
2 | 非同步處理必須已經開始 |
3 | 等待並斷言非同步結果 |
4 | 手動執行非同步分派 (因為沒有執行中的容器) |
5 | 驗證最終響應 |
@Test
fun test() {
var mvcResult = mockMvc.get("/path").andExpect {
status { isOk() } (1)
request { asyncStarted() } (2)
// TODO Remove unused generic parameter
request { asyncResult<Nothing>("body") } (3)
}.andReturn()
mockMvc.perform(asyncDispatch(mvcResult)) (4)
.andExpect {
status { isOk() } (5)
content().string("body")
}
}
1 | 檢查響應狀態是否未改變 |
2 | 非同步處理必須已經開始 |
3 | 等待並斷言非同步結果 |
4 | 手動執行非同步分派 (因為沒有執行中的容器) |
5 | 驗證最終響應 |