Spring Boot请求全量验证测试:自定义Validator注入失败
我明白你遇到的问题了——测试类里的Mock依赖能正常注入,但自定义Validator里的userRestService和profileService却都是null。这背后的原因很简单:你手动创建的LocalValidatorFactoryBean并没有纳入Spring容器的管理范畴,它初始化的自定义Validator自然没法获取到Spring上下文里的Mock Bean。
下面是具体的修复方案,分两步走:
第一步:让LocalValidatorFactoryBean由Spring容器管理
修改你的ValidationTestConfiguration配置类,把LocalValidatorFactoryBean注册为Spring Bean,这样它会自动关联Spring上下文,给自定义Validator注入依赖:
@Configuration @ComponentScan(basePackageClasses = ProfileValidator.class) // 扫描自定义Validator所在包 public class ValidationTestConfiguration { @Bean @Primary public IProfileService profileService() { return Mockito.mock(IProfileService.class); } @Bean @Primary public IUserRestService userRestService() { return Mockito.mock(IUserRestService.class); } // 注册由Spring管理的Validator @Bean public Validator validator() { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setProviderClass(HibernateValidator.class); validator.afterPropertiesSet(); return validator; } }
这里加上@ComponentScan是为了让Spring扫描到你的ProfileValidator(因为它标注了@Component),确保它被Spring管理,这样依赖才能被注入。
第二步:在测试类中注入Spring管理的Validator
删掉测试类里手动创建LocalValidatorFactoryBean的代码,改为注入Spring容器中的Validator:
@RunWith(SpringRunner.class) @ContextConfiguration(classes = {ValidationTestConfiguration.class}) public class UserCreationRequestValidationTest { @Autowired private Validator validator; // 注入Spring管理的Validator @Autowired private IProfileService profileService; @Autowired private IUserRestService restService; // 删掉原来的@BeforeClass和@AfterClass代码 @Test public void validateUserCreationRequestStringfields() { UserCreationRequest userCreationRequest = new UserCreationRequest(); /* 此处填充测试对象*/ when(profileService.getProfile(any(Integer.class), any(Integer.class))).thenReturn(new ProfileEntity()); when(restService.getRestUser()).thenReturn(new RestUser()); Set<ConstraintViolation<UserCreationRequest>> violations = validator.validate(userCreationRequest); assertEquals(violations.size(), 8); } }
为什么原来的方式不行?
你之前手动new LocalValidatorFactoryBean(),这个实例完全脱离了Spring上下文。它初始化ProfileValidator的时候,不会通过Spring的依赖注入机制去给profileService和userRestService赋值,自然就都是null了。而改成由Spring管理Validator后,所有相关的Bean都会在Spring的控制下完成依赖注入,问题就解决了。
内容的提问来源于stack exchange,提问作者Voljega

