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

时间:2017-12-11 12:21:19

标签: spring-mvc spring-boot

我试图为我的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 个答案:

答案 0 :(得分:1)

@Validated在参数上无法正常工作。您必须在参数上使用@Valid,并在方法或类级别上添加@Validated和组。

这种方式有效:

@Service
@Validated
public class MyService {

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

不幸的是我发现无法在参数级别上拥有该组。

答案 1 :(得分:0)

您可以这样做:

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