我有一个“AllowedValuesValidator.java“类:
public class AllowedValuesValidator implements ConstraintValidator<AllowedValues, String> {
String[] values;
String defaultValue;
@Override
public void initialize(AllowedValues constraintAnnotation) {
values = constraintAnnotation.allowedValues();
defaultValue = constraintAnnotation.defaultValue();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (!StringUtils.isEmpty(defaultValue) && StringUtils.isEmpty(value)) {
value = defaultValue;
}
if (!StringUtils.isEmpty(value) && !Arrays.asList(values).contains(value)) {
return false;
}
return true;
}
}
和相应的接口类:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AllowedValuesValidator.class)
public @interface AllowedValues {
String message();
String fieldName();
int fieldNumber();
String[] allowedValues() default {"Y", "N"};
String defaultValue() default "";
}
我希望能够编写一个单元测试类来测试验证器中的直接逻辑。但似乎我在谷歌上搜索的大多数地方都给予了测试类的例子,我们基本上测试了给定Model类的所有验证器,例如:
@BeforeClass
public static void setup() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
public void testEmailExistsIncorrect() {
Set<constraintviolation<usercredentialsdto>> violations = validator
.validate(credentials, UserCredentialsDto.class);
Assert.assertEquals(1, violations.size());
}
我不想构建模拟模型来测试所有的验证器。有没有一种方法可以创建一个单独的测试类,直接在一个验证器中测试逻辑,而不使用任何其他模型类等?
6条答案
按热度按时间dluptydi1#
您可以独立测试验证器。这个问题当然是initialize方法,因为它需要一个注解的示例。你基本上有三个选择:
1.添加第二个initialize方法,该方法直接接受所需的参数。然后可以使用此方法初始化验证器。您还可以使此方法仅包可见,只要您的测试驻留在同一个包中
1.将测试注解放在测试类中的某个地方,并通过反射检索它,以便将其传递给初始化方法。
1.使用注解代理。这也是Hibernate Validator本身在内部使用的,以防通过XML配置约束或测试需要约束。在Hibernate Validator中有两个类,你可以使用
AnnotationDescriptor
和AnnotationFactory
。这段代码有点像这样:您需要依赖Hibernate Validator内部类,但出于测试目的,这应该没问题。当然,您也可以创建自己的代理框架。
eivnm1vs2#
我使用了下面的模式:
我们可以模拟我们正在测试的类。由于注解只是一个接口,我们可以传入一个具体的实现作为初始化的参数(为了正确初始化测试,您可以使其以任何方式运行)。然后,您可以将mock
ConstraintValidatorContext
传递给isValid
方法。但是,您可能需要做一些额外的工作,这取决于该方法的作用,如果它与上下文交互,您可能需要做一些进一步的模拟。9ceoxa923#
注解:
验证器:
测试用例:
bjp0bcyl4#
正如@Rammgarot建议的那样,它工作得很好,但如果我们改变他的代码,例如验证规则必须是下一个:“没有白色”,并且必须以单词“stack”开始
NoWhitesSpace.java
NoWhitespacesValidator.java
测试将不会通过,代码将生成NullPointerException。
对我来说,我用mock找到了解决方案。
-> Customer是一个简单的类实体,包含字段、setter和getter。
NoWhitespacesValidatorTest.java
epggiuax5#
@哈代的答案很好,但如果你使用hibernate-validator-6.5.1.Final,@Hardy使用的构造函数AnnotationDescriptor有另一个参数,而且它是私有的。您可以检查AnnotationDescriptor构造函数here。所以我到目前为止所做的,只是把@Rammgarot和@JCollerton的答案结合起来。这是另一种测试验证器的方法。
nwwlzxa76#
我不觉得嘲笑别人很方便。相反,约束应该是可测试的,通过使用框架本身。这就是我如何设法使约束验证与Sping Boot 项目一起工作。
我并没有提供约束本身的代码(与周围的示例没有区别),而只是提供了一种实际测试它的干净方法。
1.在src/test创建一个简单的服务。(不要仅仅为了测试目的而在src/main中创建一个dummy-service)
1.创建SpringBoot测试。
}