Spring 使用自定义验证启动测试实体字段验证

Spring Boot test entity field validation with custom validation

设置:

实体字段可以使用简单的 javax.validation 约束进行注释,例如 @Positive.

@Entity
@Data
@Builder
public class Person {
    @Id
    @GeneratedValue
    private long id;

    @Column
    @Positive(message="not positive")
    private int age;
}

这很容易测试:

public class PersonTest {

    private Validator validator;

    @BeforeEach
    public void before() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void invalid_becauseNegativeAge() {
        Person uut = Person.builder().age(-1).build();
        Set<ConstraintViolation<Person>> actual = validator.validate(uut);
        assertThat(actual.iterator().next().getMessage()).isEqualTo("not positive");
    }
}

现在我将自定义验证器添加到 Person:

@Entity
@Data
@Builder
public class Person {
    @Id
    @GeneratedValue
    private long id;

    @Column
    @Positive(message="not old enough")
    private int age;

    @ComplexValueConstraint
    private String complexValue;
}

自定义注释:

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ComplexValueValidator.class)
public @interface ComplexValueConstraint {

    String message() default "too simple";    
    Class<?>[] groups() default {};    
    Class<? extends Payload>[] payload() default {};
}

自定义验证器:

class ComplexValueValidator implements ConstraintValidator<ComplexValueConstraint, Person> {

    @Override
    public boolean isValid(final Person person, final ConstraintValidatorContext context) {
    String complexValue = person.getComplexValue();
    if (complexValue.length() < 5) {
        return false;
    }
    return true;
    }
}

现在,我上面的测试失败了

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'ComplexValueConstraint' validating type 'java.lang.String'. Check configuration for 'complexValue'

我怎样才能使这个测试再次起作用?我知道我可以单独测试验证器,但是我的简单注释如 @Positive 将保持未测试状态。

是因为我在测试class中手动创建了验证器吗? @Autowired 将无法正常工作。

您声明 ComplexValueValidator 验证类型为 Person 的对象:

ComplexValueValidator implements ConstraintValidator<ComplexValueConstraint, Person>

但是注释应用于 String 类型的字段而不是 Person 类型的字段:

@ComplexValueConstraint
private String complexValue;

因此出现约束无法应用于 java.lang.String 的消息。

尝试将 complexValue 类型改为 Person 类型,而不是类型 String