非同步請求
本節展示瞭如何單獨使用 MockMvc 來測試非同步請求處理。如果透過 WebTestClient 使用 MockMvc,則無需做任何特殊操作即可使非同步請求正常工作,因為 WebTestClient 會自動執行本節中描述的操作。
Servlet 非同步請求(在 Spring MVC 中受支援)的工作原理是退出 Servlet 容器執行緒,並允許應用程式非同步計算響應,之後進行非同步分派以在 Servlet 容器執行緒上完成處理。
在 Spring MVC Test 中,可以透過首先斷言生成的非同步值,然後手動執行非同步分派,最後驗證響應來測試非同步請求。下面是一個針對返回 DeferredResult、Callable 或 Reactor Mono 等響應式型別的控制器方法的示例測試。
-
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 | 驗證最終響應 |