You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit测试移除@SpringBootTest注解抛出NullPointerException原因及必要性问询

问题解答

空指针异常的触发原因

你的ExceptionInterceptor继承了Spring MVC提供的ResponseEntityExceptionHandler基类,这个基类内部包含多个需要Spring容器注入的依赖属性(比如消息转换器messageConverters、内容协商管理器contentNegotiationManager等),这些属性只有在Bean被Spring托管、完成上下文初始化流程时才会被赋值,手动实例化/Mockito直接实例化的对象中,这些属性默认都是null。

当你移除@SpringBootTest注解时:

  • 测试仅通过MockitoJUnitRunner运行,Mockito会自行实例化ExceptionInterceptor的Spy对象,该实例没有经过Spring的初始化流程,父类的所有依赖属性都是null
  • 你声明的handleAysUserProvisException方法被final修饰,Mockito默认无法代理final方法,调用该方法时会触发父类的隐式校验/处理逻辑,用到了null的依赖属性,就抛出了空指针。

当你添加@SpringBootTest注解时:

  • Spring会启动应用上下文,扫描到标注了@ControllerAdvice的ExceptionInterceptor,将它实例化为Spring托管的Bean,自动完成父类所有依赖属性的注入
  • 此时你对该Bean做Spy增强,所有依赖都是有效值,自然不会触发空指针。

@SpringBootTest在当前场景的必要性

严格来说,你当前的测试场景(仅验证自定义异常处理方法的返回值逻辑)其实不需要用到@SpringBootTest,启动完整Spring上下文会大大增加测试耗时。你可以通过以下改造去掉该注解:

  • 移除handleAysUserProvisException方法的final修饰符,让Mockito可以正常代理Spy对象的方法
  • 如果你的其他异常处理逻辑没有用到ResponseEntityExceptionHandler提供的默认异常处理能力,也可以直接去掉继承关系,避免依赖Spring注入的属性
  • 直接实例化ExceptionInterceptor对象做测试,不需要Spy/Mock相关的注解

内容的提问来源于stack exchange,提问作者qjonn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:54:03