当前位置: 首页 > 知识库问答 >
问题:

在JSR 303 bean验证单元测试中,如何检查违反了哪些约束

卢阳泽
2023-03-14

我正试图为bean验证编写一个jUnit测试。我阅读了如何使用JUnit测试类的验证注释?并编写了如下的测试代码。

我的环境:

  • Sprint Boot 2.2.6
  • Java11
  • 断言J 3.15.0

目标Bean类:

public class Customer {

    @NotEmpty
    private String name;

    @Min(18)
    private int age;

    // getter and setter
}

JUnit测试代码:

public class CustomerValidationTest {
    private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    @Test
    public void test() {

        Customer customer = new Customer(null, 18);

        Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
        assertThat(violations.size()).isEqualTo(1); // check violations count

        // check which constraints are violated by the message of the violation
        assertThat(violations).extracting("message").containsOnly("must not be empty");
    }
}

我想检查违反了哪些约束。现在,我检查违规信息。有更好的方法吗?

共有2个答案

顾学真
2023-03-14

本教程如第7节所示。”测试。。验证..'一种很好的假设预期冲突是集合的一部分的方法

根据您的测试框架,这可能是一种需要遵循的策略。

@Test public void validatingObject() {
    Car car = new Car();
    Set<ConstraintViolation> violations = validator.validate(car);
    assertThat(violations.size()).isEqualTo(1);

    assertThat(violations)
      .anyMatch(havingPropertyPath("customerPropertyPathForCarViolation")
      .and(havingMessage("message of desired violation"))); }
石俊雄
2023-03-14

在您的小型测试设置中,您可能能够监督是否发生了准确且仅发生了一次违规。

assertThat(violations.size()).isEqualTo(1);

.containsOnly("must not be empty")

然而,在更大的设置中,情况可能并非如此。您实际上想做的是断言您预期的违规存在。

使用Testframework junit jupiter api:5.6.2,我的测试如下:

public class CustomerValidationTest {
private static Validator validator;
private static ValidatorFactory factory;

@org.junit.jupiter.api.BeforeEach
void setUp() {
    Locale.setDefault(Locale.ENGLISH);  //expecting english error messages
    factory = Validation.buildDefaultValidatorFactory();
    validator = factory.getValidator();
}

@org.junit.jupiter.api.AfterEach
void tearDown() {
    factory.close();
}

@org.junit.jupiter.api.Test
public void testContainsEmptyNameViolation() {

    Customer customer = new Customer(null, 18);

    //perform validation
    Set<ConstraintViolation<Customer>> constraintViolations = validator.validate(customer);

    boolean hasExpectedPropertyPath = constraintViolations.stream()
            .map(ConstraintViolation::getPropertyPath)
            .map(Path::toString)
            .anyMatch("name"::equals);
    boolean hasExpectedViolationMessage = constraintViolations.stream()
            .map(ConstraintViolation::getMessage)
            .anyMatch("must not be empty"::equals);

    assertAll(
            () -> assertFalse(constraintViolations.isEmpty()),
            () -> assertTrue(hasExpectedPropertyPath),
            () -> assertTrue(hasExpectedViolationMessage)
    );

即使你要求AssertJ,我希望这可能仍然对你有帮助。

 类似资料:
  • 我有一个迁移脚本之间的2个不同的模式数据库。脚本做了3件事:1。禁用约束2。将记录从旧架构插入到新架构3。启用约束 我发现这两个约束在旧的模式中是不存在的。这2个表的表结构定义有什么问题吗?

  • 这个问题与“比较方法违反了它的一般契约!”——TimSort和GdriLayout以及其他几个类似的“违反一般契约”问题有关。我的问题特别与Ceekay在页面底部关于“如何测试TimSort实现”的回答有关。在我的例子中,我已经修复了由于对称性违反而将我带到这里的应用程序错误,但是我在创建一个单元来暴露该违规(如果修复被注释掉或将来未修复)时遇到了问题。 我省略了所有实现细节,但基本上 Tick

  • 我认为违反的原则可以是开闭的,但我如何解决这个问题?

  • 我在网上读了一些讨论。他们说,我们不应该对私有方法进行单元测试或检查私有状态,因为这是实现细节,是糟糕设计的标志。但就我而言,我真的不知道如何做得更好。 下面是一个示例代码(我的实际代码是使用factory编写的,但我尝试使用纯js创建一个相同的案例,这样每个人都更容易理解,因为相同的原因是闭包): 在我真正的应用程序中,我可以注入和模拟本地存储,但这是一个问题。我的问题是如何测试方法是否设置了其

  • 问题内容: 我需要知道现在正在按下哪个键。我不是要捕获一些特定的键来触发事件或类似的事情, 我想知道现在按下了哪些键并显示它们的列表。 我还需要捕获特殊键,例如F1 … F12,Shift,Alt,Home,Windows等。基本上,键盘上的所有键都是如此。 我该如何在python中做到这一点?如何捕获键盘事件? 编辑 就是这样,您知道我不是要创建键盘记录程序。我正在尝试做一个诊断工具(我在笔记本

  • 我有一个JavaWeb7项目,在该项目中,我希望在每个事件上,直接在支持bean中管理的实体实例上编写JSF组件值。只要添加一个JSR303验证约束,就可以很好地工作,比如在实体属性之一上添加。只要违反约束,就不再在具有约束的属性上设置值。没有根据NetBeans调试器调用setter;另一个属性工作很好,这使我相信我已经隔离了问题。我想在我想要的时候执行验证,因此,如果我想要的话,可以设置无效的