I have a static method with parameters and constraints. I want to run some unit tests but when I call executableValidator.validateParameters, no violations issues are raised (it should be)
I run some reflection code and I display correctly the validation annotation in the log.
My class with the static method:
public class DiceRoller {
private DiceRoller(){}
public static int roll(@Max(20) @Valid Integer number, @DiceConstraint @Valid Integer sides){
return (int) Math.floor(Math.random() * ((sides * number)-number) + number);
}
}
The constraint interface:
@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DiceValidator.class)
public @interface DiceConstraint {
String message() default "You have to choose between dice with 2,4,6,8,10,12,20 or 100 sides";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
the validator class:
public class DiceValidator implements ConstraintValidator<DiceConstraint, Integer> {
protected int validSides [] = {2,4,6,8,10,12,20,100};
@Override
public boolean isValid(Integer sides, ConstraintValidatorContext constraintValidatorContext) {
return Arrays.stream(validSides).anyMatch(i -> i == sides.intValue());
}
}
and my test:
@SpringBootTest(classes = {SpringBootCharacterApplication.class})
public class DiceRollerCoCTest {
private static ValidatorFactory factory;
private static Validator validator;
private static ExecutableValidator executableValidator;
@BeforeEach
public void setUp() {
if (factory == null) {
factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
executableValidator = validator.forExecutables();
}
}
@Test
void roll() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
log.debug("Test of DiceRoller.roll(1000, 1000)");
Method roll = DiceRoller.class.getDeclaredMethod("roll", Integer.class,Integer.class);
Annotation[][] parameterAnnotations = roll.getParameterAnnotations();
Arrays.stream(parameterAnnotations)
.forEach(v->
Arrays.stream(v)
.forEach(vv -> log.debug(vv.toString())) );
log.debug("Invocation " + roll.invoke(null, 1000, 1000));
Object [] parameterValues = {1000, 1000};
Set<ConstraintViolation<Object>> violations
= executableValidator.validateParameters(
DiceRoller.class,
roll,
parameterValues);
log.debug(violations.size());
}
}
On the last part:
Object [] parameterValues = {1000, 1000};
Set<ConstraintViolation<Object>> violations
= executableValidator.validateParameters(
DiceRoller.class,
roll,
parameterValues);
log.debug(violations.size());
The violations size should be equal to 2 but it is equal to 0.
I have also a RestController using the method with the @Validated annotation on top and in this case it is working. So I'm waiting the same behavior when I run this unit test.
What is my mistake? Thanks