测试验证约束

发布于 2024-10-19 04:24:58 字数 1276 浏览 1 评论 0原文

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来协助单元测试限制。

The Hibernate Validator documentation has a simple Getting Started guide which outlines testing validation rules.

The relevant chunk is

@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());
}

It seems to me a fairly vague route to test if the NotNull constraint has been violated.

My simple solution would be something like

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;
}

Which allows me to do tests like

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

However, I'm sure this is going to be naive in the long run and am wondering if there's not some other library or API I'm missing to assist in unit testing constraints.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾`听者〃 2024-10-26 04:24:58

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

请注意,此类不是 Hibernate Validator 公共 API 的一部分,因此最好仅使用它来获得一些想法。

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

You could have a look at the class org.hibernate.validator.test.util.TestUtil which is used for Hibernate Validator's own tests and offers functionality for testing expected constraint violations (amongst others there is assertCorrectConstraintTypes() for example).

Just note, that this class is not part of Hibernate Validator's public API, so it may be best to just use it to get some ideas.

When comparing error messages always be sure to have the VM's locale correctly set. Even better is to match against localized messages loaded via the correct resource bundle (org.hibernate.validator.ValidationMessages for the standard constraints in the case of Hibernate Validator).

时光暖心i 2024-10-26 04:24:58

针对具体约束类测试 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");
        }
    }
}

Testing the bean validation against a concrete constraint class is a bad idea because will tightly couple the test with the implementation. So, instead of this:

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

You could test the outcome of the validation to be that of what you expect:

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

So you tests will become like this

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

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

The utility class that provides the matchers is

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");
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文