代码之家  ›  专栏  ›  技术社区  ›  UNIQUEorn

Spring Boot:如何使用@Validated annotation在JUnit中测试服务?

  •  5
  • UNIQUEorn  · 技术社区  · 7 年前

    我正在尝试为我的Spring Boot应用程序构建一组约束验证器。我想构建一些验证注释,如 @NotNull . 顺便说一句:验证应该支持验证组。

    因此,我有一个带有验证注释的简单项目模型:

    public class Item {
        @NotNull(groups=OnCreate.class) // Not Null on validation group 'OnCreate'
        private String mayNotBeNull;
    
        // Constructors and getter/setter stuff.
    }
    

    然后,我使用一个 已验证 服务:

    @Service
    @Validated
    public class MyService {
        public Item create(@Validated(OnCreate.class) Item item) {
            Item savedItem = repository.save(item);
            return savedItem;
        }
    }
    

    现在,我想在不启动全面MVC测试的情况下测试此服务(这将启动所有REST控制器和我不需要的东西)。

    我开始写我的测试:

    @ContextConfiguration(classes = {
    ItemRepository.class, MyService.class, LocalValidatorFactoryBean.class
    })
    @RunWith(SpringRunner.class)
    public class PlantServiceTest {
    
      @MockBean
      private ItemRepository repository;
    
      @Autowired
      private MyService service;
    
      @Autowired
      private Validator validator;
    
      @Test
      public void shouldDetectValidationException() {
            // ... building an invalid item
            Item item = new Item();
            item.setMayNotBeNull(null); // <- This causes the validation exception.
            validator.validate(item, OnCreate.class);
      }
    
      @Test
      public void shouldAlsoDetectValidationException() {
            // ... building an invalid item
            Item item = new Item();
            item.setMayNotBeNull(null); // <- This should cause the validation exception.
            service.create(item); // <- No validation error. Service is not validating.
      }
      }
    

    方法 shouldThrowValidationException 检测验证错误,因为项中的字段值为 null .

    方法 shouldAlsoDetectValidationException 未检测到验证错误。

    我想我在配置上下文时遗漏了一些内容。验证逻辑不扩展服务对象。

    我如何配置测试,使自动连线服务用提供的验证逻辑装饰 @Validated ?

    2 回复  |  直到 7 年前
        1
  •  7
  •   Andrew T Finnell    5 年前

    @Validated在参数上无法按预期工作。您必须在参数上使用@Valid,并在方法或类级别将@Validated添加到组中。

    其工作方式如下:

    @Service
    @Validated
    public class MyService {
    
        @Validated(OnCreate.class)
        public Item create(@Valid Item item) {
            ...
        }
    }
    

    不幸的是,我找不到将组置于参数级别的方法。

    如果要在Spring单元测试中测试验证逻辑,则必须 通过以下方式导入ValidationAutoConfiguration类:

    @Import(ValidationAutoConfiguration.class)
    
        2
  •  1
  •   Rammgarot    6 年前

    您可以这样做:

    @Spy private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    

    ...

    Object object = new...
    Method method = %your_class%.class.getMethod("%method name%", param_1.class, ..., param_n.class);
            Object[] parameterValues = { 1L, 0, null }; //e.g.
            Set<ConstraintViolation<%your_class%>> violations = executableValidator.validateParameters(object, method, parameterValues);
    
    assertEquals(%number_of_violations%, violations.size());