异步请求

本节介绍如何单独使用 MockMvc 来测试异步请求处理。如果通过 WebTestClient 使用 MockMvc,则无需进行任何特殊操作即可使异步请求生效,因为 WebTestClient 会自动执行本节所述的操作。

Servlet 异步请求,在 Spring MVC 中支持,其工作原理是退出 Servlet 容器线程,允许应用异步计算响应,之后进行异步分派以在 Servlet 容器线程上完成处理。

在 Spring MVC Test 中,可以通过先断言生成的异步值,然后手动执行异步分派,最后验证响应来测试异步请求。下面是返回 DeferredResultCallable 或 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 验证最终响应