使用Mockito和Autowiring的JSR 303 bean验证单元测试 [英] JSR 303 bean validation unit testing with Mockito and Autowiring
问题描述
我想通过junit测试我的验证器类,但是我的验证器类具有@autowired服务类.如何使用Mocikto注入这些依赖项?
I want to junit test my validator class but my validator class has @autowired service classes. How do I inject these dependencies using Mocikto?
我将使用下面的代码行调用验证器.
I am going to call the validator using below line of code.
Set<ConstraintViolation<MyDomainPOJOObject>> constraintViolationsFromJavaRules = validator.validate(myDomainPOJOObject, Default.class);
问题是我自己没有实例化验证器类.真正调用验证程序的isValid method()的是JSR 303框架.
Problem is I am not instantiating validator class myself. It's the JSR 303 framework which truely calls the validator's isValid method().
另一件事是我不想使用spring自动装配并使用@Mock and @InjectMock
注释.
Another thing is I don't want to use spring Autowiring and use the @Mock and @InjectMock
annotations.
有任何例子或想法吗?
我可以通过下面的代码行来使其工作
I was able to get it working by having below line of code
@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);
}
推荐答案
为此,我创建了自定义ConstraintValidatorFactory来提供我的自定义ConstraintValidator.
To achieve this I created custom ConstraintValidatorFactory to provide my custom ConstraintValidator.
假设我们有以下内容:
- SomeValidation-Bean验证约束注释
- SomeValidationValidator-具有@Autowired依赖项的Bean验证约束验证器.它包含两个构造函数:default构造函数和一个具有依赖关系的构造函数
现在,您可以创建一个测试ConsValidationValidatorTest,该测试实现ConstraintValidatorFactory并与MockitoJUnitRunner.class一起运行:
Now you can create a test SomeValidationValidatorTest that implements ConstraintValidatorFactory and is run with MockitoJUnitRunner.class:
@RunWith(MockitoJUnitRunner.class)
public class SomeValidationValidatorTest implements ConstraintValidatorFactory {
@Mock
private MyDependency myDependencyMock;
}
您必须从ConstraintValidatorFactory实现getInstance方法:
You must implement getInstance method from ConstraintValidatorFactory:
@Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
if (key == SomeValidationValidator.class) {
return (T) new SomeValidationValidator(myDependencyMock);
}
throw new IllegalArgumentException("expecting SomeValidationValidator!");
}
有了这个,您可以配置验证器:
Having this you can configure the Validator:
@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解决问题的想法.
The above solution is not perfect but I assume it gives you the idea of using custom ConstraintValidatorFactory to solve the problem.
这篇关于使用Mockito和Autowiring的JSR 303 bean验证单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!