I have an "AllowedValuesValidator.java" class:
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;
}
}
And the corresponding interface class:
@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 "";
}
I want to be able to write a unit test class to test the direct logic in that validator. But it seems that most places I googled give examples of test classes where we basically test all validators for a given Model class, for example:
@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());
}
I don't want to build mock models to test all validators. Is there a way to create a separate test class for just testing the logic in one single validator directly without using any other model classes etc?
You can test the validator standalone. The rub is of course the initialize method, since it needs an instance of the annotation. You basically have three options:
AnnotationDescriptor
and AnnotationFactory
. The code would somewhat like this:--
private AllowedValues createAnnotation(String[]values, String defaultValue) {
AnnotationDescriptor<AllowedValues> descriptor = new AnnotationDescriptor<AllowedValues>( AllowedValues.class );
descriptor.setValue( "values", values );
descriptor.setValue( "defaultValue", defaultValue );
return AnnotationFactory.create( descriptor );
}
You would need to depend on Hibernate Validator internal classes, but for testing purposes this should be fine. Of course you could also just create your own proxy framework.