如何在@SpringBootTest中启用虚拟线程?两种常规方法均无效
在@SpringBootTest中启用虚拟线程的解决方案
问题根源
MockMvc默认是模拟Servlet请求处理流程,不会启动真实的Web容器,请求会直接在测试用的平台线程中调用控制器方法,完全不走Spring Boot配置的虚拟线程调度逻辑。而用RestAssured测试时,你手动启动了完整的Spring Boot应用,真实的嵌入式容器会加载虚拟线程配置,所以控制器能运行在虚拟线程上。
可行解决方案
方案1:启动真实嵌入式容器(推荐)
给@SpringBootTest指定webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,让Spring Boot启动真实的嵌入式Tomcat容器,此时虚拟线程配置会正常生效,你可以用TestRestTemplate或者RestAssured来测试:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class DemoApplicationTests { @Autowired private TestRestTemplate restTemplate; @Test void testVirtualThreadEnabled() { Boolean result = restTemplate.getForObject("/api", Boolean.class); Assertions.assertTrue(result); } }
方案2:让MockMvc在虚拟线程中执行请求
如果一定要用MockMvc,可以将请求执行逻辑放到虚拟线程中,确保控制器方法运行在虚拟线程上:
@SpringBootTest class DemoApplicationTests { @Autowired protected MockMvc mockMvc; @Test void testing_with_MockMvc() throws Exception { // 提交到虚拟线程执行器运行请求 Executors.newVirtualThreadPerTaskExecutor() .submit(() -> { try { var response = mockMvc.perform(MockMvcRequestBuilders.get("/api")) .andExpect(status().isOk()) .andReturn(); Assertions.assertEquals("true", response.getResponse().getContentAsString()); } catch (Exception e) { throw new RuntimeException(e); } }).get(); } }
另外,确保你的Spring Boot版本支持虚拟线程(3.2+),并且已经正确配置:
- 在
application.properties中添加spring.threads.virtual.enabled=true - 或者通过Bean配置虚拟线程池:
@Bean public TaskExecutor applicationTaskExecutor() { return new VirtualThreadTaskExecutor(); }
内容的提问来源于stack exchange,提问作者Jimmy Tovar Rodríguez
相关产品推荐
相关产品推荐

