JUnit测试带自定义Validator的控制器时因Util返回空抛出Null Pointer异常
自定义Validator单元测试instance空指针解决方案
核心原因
你遇到的空指针本质是自定义校验器中依赖的Spring管理Bean(比如负责数据库查询的Service/DAO实例)没有被正确注入,静态工具类从上下文拿Bean时找不到对应实例,最终返回null。
具体解决步骤
先确认基础配置正确性
你的静态上下文工具类必须加@Component注解,确保Spring启动时自动扫描到并注入ApplicationContext,不要漏写注解导致工具类本身未被Spring管理。调整单元测试上下文配置(走完整Spring测试环境的场景)
如果你用@SpringBootTest做集成测试,确保注解的扫描范围包含自定义Validator、上下文工具类、依赖的数据库操作类:
如果你手动构建MockMvc做单独测试,不要用默认的Validator实例,要从Spring上下文拿已经注入完成的Validator绑定到MockMvc:// 示例配置,把涉及的类都加载到测试上下文 @SpringBootTest(classes = {YourApp.class, CustomValidator.class, SpringContextUtil.class, UserMapper.class}) @AutoConfigureMockMvc public class ControllerTest { @Autowired private MockMvc mockMvc; // 测试逻辑 }@Autowired private Validator validator; private MockMvc mockMvc; @Autowired private YourController yourController; @BeforeEach void initMockMvc() { mockMvc = MockMvcBuilders.standaloneSetup(yourController) .setValidator(validator) // 关键配置,替换默认的无注入Validator .build(); }纯单元测试场景(不启动Spring上下文)
不需要真实调用数据库的话,直接mock对应的依赖即可,避免上下文加载成本:// 1. mock你需要调用的数据库操作实例 UserService userService = Mockito.mock(UserService.class); Mockito.when(userService.checkUserIdExist(1L)).thenReturn(true); // 2. mock静态上下文工具类的getBean方法,返回mock好的实例 try (MockedStatic<SpringContextUtil> mockedUtil = Mockito.mockStatic(SpringContextUtil.class)) { mockedUtil.when(() -> SpringContextUtil.getBean(UserService.class)).thenReturn(userService); // 执行你的测试逻辑 }
注意事项
- 不要在自定义Validator里手动new依赖的Bean,所有需要Spring管理的对象必须从Spring上下文获取
- 测试环境如果做了Bean扫描过滤,要确保自定义Validator和上下文工具类没有被排除在扫描范围外
内容的提问来源于stack exchange,提问作者Ramakrishna Patil
相关产品推荐
相关产品推荐

