首页 > 解决方案 > 如何在 JUnit 中验证静态方法的参数?

问题描述

我有一个带有参数和约束的静态方法。我想运行一些单元测试,但是当我调用 executableValidator.validateParameters 时,没有引发违规问题(应该是)

我运行了一些反射代码,并在日志中正确显示了验证注释。

我的类使用静态方法:

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);
    }

}

约束界面:

@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 {};

}

验证器类:

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());

    }
}

和我的测试:

@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());

    }
}

在最后一部分:

Object [] parameterValues = {1000, 1000};
        Set<ConstraintViolation<Object>> violations
                = executableValidator.validateParameters(
                        DiceRoller.class,
                        roll,
                        parameterValues);
        log.debug(violations.size());

违规大小应等于 2,但等于 0。

我还有一个 RestController 使用顶部带有 @Validated 注释的方法,在这种情况下它正在工作。所以当我运行这个单元测试时,我正在等待同样的行为。

我的错误是什么?谢谢

标签: javajakarta-eejavax.validation

解决方案


“bean 验证框架”这个名称表明它仅适用于 Java Bean,它们始终是对象,静态方法在技术上不属于 Bean 的概念。

这是本页的第一条语句:https ://javaee.github.io/tutorial/bean-validation004.html

“Bean Validation 约束可以放在非静态方法和构造函数的参数以及非静态方法的返回值上。静态方法和构造函数将不会被验证。”


推荐阅读