Тестирование проверочных ограничений - PullRequest
2 голосов
/ 23 февраля 2011

Документация по Hibernate Validator содержит простое руководство по началу работы, в котором изложены правила проверки .

Соответствующий фрагмент -

@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, которые мне не хватает, чтобы помочь в ограничениях модульного тестирования.

Ответы [ 2 ]

3 голосов
/ 28 мая 2011

Вы можете взглянуть на класс org.hibernate.validator.test.util.TestUtil, который используется для собственных тестов Hibernate Validator и предлагает функциональность для тестирования ожидаемых нарушений ограничений (среди прочего, например, assertCorrectConstraintTypes()).

Просто отметьте, что этот класс не является частью общедоступного API Hibernate Validator, поэтому лучше всего использовать его для получения некоторых идей.

При сравнении сообщений об ошибках всегда убедитесь, что языковой стандарт виртуальной машины установлен правильно. Еще лучше сопоставить локализованные сообщения, загруженные через правильный пакет ресурсов (org.hibernate.validator.ValidationMessages для стандартных ограничений в случае Hibernate Validator).

1 голос
/ 07 апреля 2014

Тестирование проверки 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");
        }
    }
}
...