为什么@WebMvcTest未自动将ControllerAdvice加载到应用上下文?
问题原因与解决方法
为什么需要手动配置上下文
@WebMvcTest 是Spring Boot提供的Web层切片测试注解,默认仅会扫描当前测试工程自身包路径下的Web相关组件(包括@Controller、@ControllerAdvice、@JsonComponent等),不会扫描第三方依赖Jar包中的对应组件,这是切片测试缩小上下文加载范围、提升测试启动速度的默认设计。
你自定义的异常处理类存放在第三方starter中,自然不在默认扫描范围内,因此不会被自动注册到测试上下文,ConstraintViolationException抛出时没有对应的异常处理器处理,就会被Servlet容器包装成NestedServletException抛出。
你手动添加@ContextConfiguration指定加载SomeExceptionHandler,相当于强制将该异常处理类注册到测试上下文,因此异常处理逻辑可以正常生效,接口返回预期的400状态码。
无需添加@ContextConfiguration的解决方法
- 方法1:使用@WebMvcTest的includeFilters属性主动引入第三方异常处理类
直接在@WebMvcTest注解中添加过滤规则,指定加载你需要的ControllerAdvice即可,不需要额外加@ContextConfiguration:@ExtendWith(SpringExtension.class) @WebMvcTest( value = SomeController.class, includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SomeExceptionHandler.class) ) @WithMockUser("123@domain.de") class SomeControllerIntegrationTest { // 测试逻辑保持不变 } - 方法2:修改第三方starter的自动配置(可修改starter的前提下最优)
如果你有权限修改引入的第三方starter,可以将SomeExceptionHandler的注册逻辑放到starter的自动配置类中,Spring Boot的切片测试会自动加载第三方starter的自动配置类,这样所有使用@WebMvcTest的测试都能自动识别到该异常处理类,无需做任何额外配置。 - 方法3:封装测试专用组合注解(多测试类复用场景适用)
如果你的项目中有多个Web层测试都需要用到这个异常处理类,可以自定义一个组合测试注解,把includeFilters的逻辑封装进去,避免每个测试类重复配置。
内容的提问来源于stack exchange,提问作者Nico S.
相关产品推荐
相关产品推荐

