1

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がないかどうか疑問に思っています。

4

2 に答える 2

2

org.hibernate.validator.test.util.TestUtilHibernate Validator自身のテストに使用され、予想される制約違反をテストするための機能を提供するクラスを見ることができます(assertCorrectConstraintTypes()たとえば、他にもあります)。

このクラスはHibernateValidatorのパブリックAPIの一部ではないため、アイデアを得るためにこのクラスを使用するのが最適な場合があることに注意してください。

エラーメッセージを比較するときは、常にVMのロケールが正しく設定されていることを確認してください。さらに良いのは、正しいリソースバンドルを介してロードされたローカライズされたメッセージと照合することです(org.hibernate.validator.ValidationMessagesHibernate Validatorの場合の標準的な制約の場合)。

于 2011-05-28T15:31:46.743 に答える
1

具体的な制約クラスに対してBeanValidationをテストすることは、テストと実装を緊密に結合するため、お勧めできません。したがって、これの代わりに:

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");
        }
    }
}
于 2014-04-07T10:21:46.343 に答える