使用Mockito和Autowiring进行JSR 303 bean验证单元测试

时间:2014-11-21 13:34:11

标签: validation unit-testing mockito junit4

我想对我的验证器类进行junit测试,但我的验证器类有@autowired服务类。如何使用Mocikto注入这些依赖项?

我将使用以下代码行调用验证器。

Set<ConstraintViolation<MyDomainPOJOObject>> constraintViolationsFromJavaRules = validator.validate(myDomainPOJOObject, Default.class);

问题是我自己没有实例化验证器类。它是JSR 303框架,它真正调用验证器的isValid方法()。

另一件事是我不想使用spring Autowiring并使用@Mock and @InjectMock注释。

任何示例或想法?

我能够通过下面的代码行来实现它的工作

@Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
    if (key == com.nitin.validation.UpperCaseValidator.class) {
        return (T)upperCasevalidator;
    }
    //throw new IllegalArgumentException("expecting SomeValidationValidator!");
    return new ConstraintValidatorFactoryImpl().getInstance(key);
}

1 个答案:

答案 0 :(得分:10)

为实现这一点,我创建了自定义ConstraintValidatorFactory来提供我的自定义ConstraintValidator。

假设我们有以下内容:

  1. SomeValidation - Bean Validation约束注释
  2. SomeValidationValidator - 具有@Autowired依赖关系的Bean Validation约束验证程序。它包含两个构造函数:default和带依赖性的构造函数
  3. 现在您可以创建一个实现ConstraintValidatorFactory的测试SomeValidationValidatorTest,并使用MockitoJUnitRunner.class运行:

    @RunWith(MockitoJUnitRunner.class)
    public class SomeValidationValidatorTest implements ConstraintValidatorFactory {
        @Mock
        private MyDependency myDependencyMock;
    }
    

    您必须从ConstraintValidatorFactory实现getInstance方法:

    @Override
    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
        if (key == SomeValidationValidator.class) {
            return (T) new SomeValidationValidator(myDependencyMock);
        }
        throw new IllegalArgumentException("expecting SomeValidationValidator!");
    }
    

    有了这个,您可以配置验证器:

    @Before
    public void setUp() throws Exception {
    
        // see https://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html/chapter-bootstrapping.html#_constraintvalidatorfactory
        Configuration<?> config = Validation.byDefaultProvider().configure();
        config.constraintValidatorFactory(this);
    
        ValidatorFactory factory = config.buildValidatorFactory();
    
        validator = factory.getValidator();
    }
    

    最后创建一些测试:

    @Test
    public void someTest1() {
        // arrange
        Bean bean = new Bean();
        Mockito.when(myDependencyMock.isValid(null)).thenReturn(true);
        // act
        Set<ConstraintViolation<Bean>> constraintViolations = validator.validate(bean);
        // assert
        Assert.assertTrue(constraintViolations.isEmpty());
        Mockito.verify(myDependencyMock).isValid(null);
    }
    

    上述解决方案并不完美,但我认为它可以让您使用自定义ConstraintValidatorFactory来解决问题。