单元测试中如何获取仅配置ValidatorA的Validator实例?
如何在单元测试中仅使用指定的ConstraintValidator验证实体
我有两个针对同一实体AnEntity的ConstraintValidator实现:
ValidatorA
public class ValidatorA implements ConstraintValidator<ValidityAnnotationA, AnEntity> { @Override public boolean isValid(final AnEntity entity, final ConstraintValidatorContext context) { // 验证逻辑 return valid; } }
ValidatorB
public class ValidatorB implements ConstraintValidator<ValidityAnnotationB, AnEntity> { @Override public boolean isValid(final AnEntity entity, final ConstraintValidatorContext context) { // 验证逻辑 return valid; } }
在ValidatorA的单元测试中,我希望仅用ValidatorA来验证对象(不想触发ValidatorB的逻辑或副作用)。但使用Validation.buildDefaultValidatorFactory().getValidator();会同时启用两个验证器,请问该如何获取仅配置了ValidatorA的Validator实例?
我曾考虑过创建自定义ConstraintValidatorFactory并注入到Validation上下文,但不知具体如何操作,只找到如下代码片段:
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); validatorFactory.usingContext().constraintValidatorFactory(myCustomFactory);
注:约束分组在我的场景中不可行。
解决方案:自定义ConstraintValidatorFactory限制仅加载指定验证器
通过实现自定义的ConstraintValidatorFactory,我们可以控制只实例化和返回需要的ValidatorA,拒绝其他Validator的创建请求,具体步骤如下:
- 实现自定义ConstraintValidatorFactory
public class SingleValidatorFactory implements ConstraintValidatorFactory { private final Map<Class<?>, ConstraintValidator<?, ?>> validatorCache = new HashMap<>(); public SingleValidatorFactory() { // 预先初始化并缓存需要的ValidatorA validatorCache.put(ValidatorA.class, new ValidatorA()); } @Override public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> validatorClass) { // 仅允许返回ValidatorA,其他类型直接抛出异常(也可根据需求返回null) if (ValidatorA.class.isAssignableFrom(validatorClass)) { return validatorClass.cast(validatorCache.get(validatorClass)); } throw new UnsupportedOperationException("本Factory仅支持加载ValidatorA"); } @Override public void releaseInstance(ConstraintValidator<?, ?> instance) { // 若Validator有资源需要释放,可在此实现;无需则留空即可 } }
- 构建仅包含ValidatorA的Validator实例
// 通过自定义配置构建ValidatorFactory ValidatorFactory validatorFactory = Validation.byDefaultProvider() .configure() .constraintValidatorFactory(new SingleValidatorFactory()) .buildValidatorFactory(); // 获取仅启用ValidatorA的Validator实例 Validator validator = validatorFactory.getValidator();
原理说明
这种方式会拦截所有Validator的创建请求,仅允许实例化ValidatorA。当验证框架尝试加载ValidatorB时,会触发我们定义的异常,从而避免其逻辑被执行,完全隔离ValidatorA的测试环境。
内容的提问来源于stack exchange,提问作者Balázs Fodor-Pap
相关产品推荐
相关产品推荐

