Spring 使用自定义验证启动测试实体字段验证
Spring Boot test entity field validation with custom validation
设置:
- Spring 引导 2.3.3(spring-引导启动程序验证)
- JUnit 5 木星
- 龙目岛
实体字段可以使用简单的 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
。
设置:
- Spring 引导 2.3.3(spring-引导启动程序验证)
- JUnit 5 木星
- 龙目岛
实体字段可以使用简单的 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
。