【问题标题】:Testing validation constraints测试验证约束
【发布时间】:2011-02-23 18:09:25
【问题描述】:

Hibernate Validator 文档有一个简单的入门指南,其中概述了testing validation rules

相关块是

@Test
public void manufacturerIsNull() {
    Car car = new Car(null, "DD-AB-123", 4);

    Set<ConstraintViolation<Car>> constraintViolations =
        validator.validate(car);

    assertEquals(1, constraintViolations.size());
    assertEquals("may not be null", constraintViolations.iterator().next().getMessage());
}

在我看来,测试 NotNull 约束是否被违反是一条相当模糊的路线。

我的简单解决方案是这样的

public static <T> boolean  containsConstraintViolation(
    Set<ConstraintViolation<T>> violations, Class<?> constraint) {

    for (ConstraintViolation<?> violation : violations) {
        ConstraintDescriptor<?> descriptor = violation.getConstraintDescriptor();
            if (constraint.isAssignableFrom(descriptor.getAnnotation().getClass()))
                return true;
        }
    return false;
}

这让我可以做类似的测试

assertTrue(ValidationUtils.containsConstraintViolation(violations, NotNull.class));

但是,我确信从长远来看这将是幼稚的,我想知道是否没有其他库或 API 可以帮助我进行单元测试约束。

【问题讨论】:

    标签: java validation junit hibernate-validator


    【解决方案1】:

    您可以查看 org.hibernate.validator.test.util.TestUtil 类,该类用于 Hibernate Validator 自己的测试,并提供测试预期约束违规的功能(其中有 assertCorrectConstraintTypes() 例如)。

    请注意,这个类不是 Hibernate Validator 的公共 API 的一部分,所以最好只是使用它来获得一些想法。

    在比较错误消息时,请务必正确设置 VM 的区域设置。更好的是匹配通过正确资源包加载的本地化消息(org.hibernate.validator.ValidationMessages 用于 Hibernate Validator 情况下的标准约束)。

    【讨论】:

      【解决方案2】:

      针对具体的约束类测试 bean 验证是一个坏主意,因为它将测试与实现紧密耦合。所以,而不是这个:

      assertTrue(ValidationUtils.containsConstraintViolation(violations, NotNull.class));
      

      您可以测试验证的结果是否符合您的预期:

      assertThat(validationFor(car, onField("manufacturer")), fails());
      

      所以你的测试会变成这样

      @Test
      public void car_with_null_manufacturer_is_invalid() {
          Car car = new Car(null, "DD-AB-123", 4);
      
          assertThat(validationFor(car, onField("manufacturer")), fails());
      }
      

      提供匹配器的实用程序类是

      public class HibernateValidationUtils {
          private static Validator VALIDATOR;
          static {
              ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
              VALIDATOR = factory.getValidator();
          }
      
          public static Set<ConstraintViolation<Object>> validationFor(Object object, String fieldname) {
              return VALIDATOR.validateProperty(object, fieldname);
          }
      
          public static String onField(String fieldname) {
              return fieldname;
          }
      
          public static Matcher<Set<ConstraintViolation<Object>>> succedes() {
              return new PassesValidation();
          }
      
          public static Matcher<Set<ConstraintViolation<Object>>> fails() {
              return new Not(new PassesValidation());
          }
      
          static class PassesValidation extends BaseMatcher<Set<ConstraintViolation<Object>>> {
              @Override
              public boolean matches(Object o) {
                  boolean result = false;
                  if (o instanceof Set) {
                      result = ((Set) o).isEmpty();
                  }
                  return result;
              }
      
              @Override
              public void describeTo(Description description) {
                  description.appendText("valid");
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-10-23
        • 1970-01-01
        • 2017-03-24
        • 1970-01-01
        • 2014-12-20
        • 2018-11-23
        • 1970-01-01
        • 2010-09-22
        • 2022-11-23
        相关资源
        最近更新 更多