【问题标题】:How to test if @Valid annotation is working?如何测试@Valid 注解是否有效?
【发布时间】:2023-03-26 02:22:01
【问题描述】:

我有以下单元测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {EqualblogApplication.class})
@WebAppConfiguration
@TestPropertySource("classpath:application-test.properties")
public class PostServiceTest {
  // ...

  @Test(expected = ConstraintViolationException.class)
  public void testInvalidTitle() {
       postService.save(new Post());  // no title
  }
}

PostServicesave 的代码是:

public Post save(@Valid Post post) {
    return postRepository.save(post);
}

Post 类在大多数字段中都标有@NotNull

问题是:没有抛出验证异常

但是,这只发生在测试中。 使用应用程序正常运行验证并抛出异常。

注意:我想自动(保存时)而不是手动验证然后保存(因为它更现实)。

【问题讨论】:

  • 该解决方案只提供了一种编程方法。:validator.validateProperty(object, propertyName) 我想要在保存时进行隐式验证
  • @Inject MockMvc mvc; 的解决方案对我来说看起来不错?
  • 好吧,我不确定 spring 中的哪个组件负责处理验证。您可以测试验证本身,但您可能需要一个集成测试(完全部署)来测试是否处理了 @valid。如需测试验证结果,请参阅jmdoudoux.fr/java/dej/chap-validation_donnees.htm 的示例§101.2.1.5
  • 你可能想了解一下MethodValidationPostProcessor

标签: java spring junit spring-boot hibernate-validator


【解决方案1】:

此解决方案适用于 Spring 5。它也应该适用于 Spring 4。 (我在 Spring 5 和 SpringBoot 2.0.0 上测试过)。

必须具备三样东西:

  1. 在测试类中,提供一个用于方法验证的 bean(在您的示例中为 PostServiceTest)

像这样:

@TestConfiguration
static class TestContextConfiguration {
   @Bean
   public MethodValidationPostProcessor bean() {
      return new MethodValidationPostProcessor();
   }
}
  1. 在方法上有@Valid注解的类中,还需要在类级别用@Validated(org.springframework.validation.annotation.Validated)注解!

像这样:

@Validated
class PostService {
   public Post save(@Valid Post post) {
       return postRepository.save(post);
   }
}
  1. 您必须在类路径中有一个 Bean Validation 1.1 提供程序(例如 Hibernate Validator 5.x)。实际的提供者将被 Spring 自动检测并自动适应。

更多详情MethodValidationPostProcessor documentation

希望有帮助

【讨论】:

  • 这似乎不适用于 Junit 5。请您帮忙
  • @Saran 在我的情况下似乎可以使用 JUnit5。
  • 你能告诉 quarkus 的解决方案吗? @Valid 注释没有按预期工作。不抛出验证错误。
【解决方案2】:

这就是我通过将ValidationAutoConfiguration.class 加载到上下文中的方法:

@SpringBootTest
@ContextConfiguration(classes = { MyComponent.class, ValidationAutoConfiguration.class
public class MyComponentValidationTest {
  
  @Autowired
  private MyComponent myComponent;

  @Test
  void myValidationTest() {
    String input = ...;
    // static import from org.assertj.core.api.Assertions
    assertThatThrownBy(() -> myComponent.myValidatedMethod(input))
      .isInstanceOf(ConstraintViolationException.class)
      .hasMessageContaining("my error message");
  }

}

还有 MyComponent 类:

@Component
@Validated
public class MyComponent {


  public void myValidatedMethod(@Size(min = 1, max = 30) String input) {
    // method body
  }

)

【讨论】:

    猜你喜欢
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多