Spring Boot如何创建多测试类复用的通用MockMvc工具类
Spring Boot 测试通用MockMvc工具类注入失败解决方案
问题根因
你之前的写法存在两个核心问题:
@AutoConfigureMockMvc是测试类专属注解,作用是触发Spring Boot自动配置MockMvc实例,标注在@Component/@TestComponent类上不会生效@SpringBootTest默认只会扫描主应用包路径下的main源码Bean,src/test目录下的@TestComponent默认不会被自动扫描到,因此找不到对应Bean
正确实现方案
步骤1:修正通用工具类定义
把@AutoConfigureMockMvc从AppMockMcv类上去掉,仅保留@TestComponent注解,确保类放在src/test/java目录下:
@TestComponent public class AppMockMcv { private static final String DISH_ENDPOINT = "/dishes"; private static final String BASE_INGREDIENTS_ENDPOINT = "/base-ingredients"; @Autowired private MockMvc mockMvc; @Autowired private ObjectMapper objectMapper; public void saveMockDish(DishDto dishDto) throws Exception { mockMvc.perform( MockMvcRequestBuilders.post(DISH_ENDPOINT) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(dishDto))) .andExpect(status().isCreated()); } public DishDto getMockDish(Long id) throws Exception { MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders .get(DISH_ENDPOINT + "/{id}", id)) .andExpect(status().isOk()) .andReturn(); String contentAsString = mvcResult.getResponse().getContentAsString(); return objectMapper.readValue(contentAsString, new TypeReference<>() { }); } public List<DishDto> getMockDishes() throws Exception { // 你的业务实现逻辑 } }
步骤2:调整测试类配置
在测试类上添加@AutoConfigureMockMvc,同时用@Import注解直接导入AppMockMcv类,强制注册这个Bean到测试上下文:
@SpringBootTest @AutoConfigureMockMvc @Import(AppMockMcv.class) public class DishControllerTest { @Autowired private AppMockMcv appMockMcv; @Test void testGetDishes() throws Exception { List<DishDto> dishes = appMockMcv.getMockDishes(); assertEquals(4, dishes.size()); assertNotNull(dishes); DishAssertions.containsDish(dishes, "Pasta Carbonara"); } }
可选优化:批量复用配置
如果有多个测试类都要用到AppMockMcv,可以自定义一个组合注解避免重复写配置:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @SpringBootTest @AutoConfigureMockMvc @Import(AppMockMcv.class) public @interface MockMvcIntegrationTest { }
后续测试类直接标注@MockMvcIntegrationTest即可直接注入AppMockMcv:
@MockMvcIntegrationTest public class DishControllerTest { @Autowired private AppMockMcv appMockMcv; // 测试方法 }
注意事项
- 所有测试专用组件必须放在
src/test/java目录下,不会被打包到生产环境 - 如果使用
@WebMvcTest切片测试,同样可以通过@Import(AppMockMcv.class)的方式注入工具类,兼容切片测试场景 - 不要给工具类添加
@SpringBootTest注解,该注解仅用于标记测试启动类
内容的提问来源于stack exchange,提问作者M. Merim
相关产品推荐
相关产品推荐

