Skip to content
Advertisement

JUnit-Testing Custom Validation Annotations Java

Hei,

I currently working on custom annotations for bean validation. To ensure the implemented validation logic is working as intended, i would like to implement unit-tests for these annotations. Sadly I am struggeling to find relevant guides/tutorials on Google.

The most obvious solution is to create some class, stick the annotation on it and use the validatorFactory to start the validation as usual. With this, we would be able to see if the expected results came in. But that approach is not a real unit-Test. Various other parts of the bean validation logic are run through to carry out the test.

I do think it would be preferrable to test the validators independently, but I have no clue how to manually do so. After creating the instance of the validator, we would need to pass the annotation to its initialize function. But how can i manually produce this instance of an annotation? Is this even possible?

Annotation-Code:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = { LongRangeValidator.class })
@Documented
public @interface LongRange {

    /**
     * Minimal valid value
     */
    long min() default 0;

    /**
     * Maximal valid value
     */
    long max() default Long.MAX_VALUE;

    String message() default "";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        LongRange[] value();
    }

}

Validator-Code:

/**
 * Validator for @LongRange-Annotation
 */
public class LongRangeValidator implements ConstraintValidator<LongRange, Long> {

    private Long min;
    private Long max;

    @Override
    public void initialize(final LongRange constraintAnnotation) {
        min = constraintAnnotation.min();
        max = constraintAnnotation.max();
    }

    @Override
    public boolean isValid(final Long value, final ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }

        return min.compareTo(value) <= 0 && max.compareTo(value) >= 0;
    }
}

Sincerely,

WorkingAccount

Advertisement

Answer

Ok, silly problem. I did not get how to instanciate an interface. I solved it as follows:

In the Test-Class I added a method for creating the instance of the Annotation. Note that all of the interface-Methods aswell als the annotationType-Method must be implemented.

private LongRange createLongRange(long min, long max) {
        return new LongRange() {
            @Override
            public long min() {
                return min;
            }

            @Override
            public long max() {
                return max;
            }

            @Override
            public String message() {
                return "MSG_1";
            }

            @Override
            public Class<?>[] groups() {
                return new Class[0];
            }

            @Override
            public Class<? extends Payload>[] payload() {
                return new Class[0];
            }

            @Override
            public Class<? extends Annotation> annotationType() {
                return LongRange.class;
            }
        };
    }

Having this method we can set up the validator for the testcase with the following logic.

private void setUp(long min, long max) {
        this.longRangeValidator = new LongRangeValidator();
        this.longRangeValidator.initialize(createLongRange(min, max));
    }

With that I am able to write unit tests for my annotation.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement