如何在webservice junit测试中忽略验证/ ConstraintValidator?

时间:2018-01-24 11:24:17

标签: java spring spring-mvc junit spring-test

我有以下简单的网络服务,将来需要LocalDate。注释是自定义注释,如下所示:

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateInFutureValidator.class)
public @interface DateInFuture {
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class DateInFutureValidator implements ConstraintValidator<DateInFuture, Temporal> {
    @Override
    public void initialize(DateInFuture constraintAnnotation) { }

    @Override
    public boolean isValid(Temporal value, ConstraintValidatorContext context) {
        //validation logic
    }
}

问题:如何在junit集成测试期间(使用过去一段时间内的日期)禁用该注释?

春天servlet:

@RestController
public class MyController {
    @PostMapping(path)
    public Rsp post(MyDTO dto) {

    }
}


public class MyDTO {
    @NotNull
    @DateInFuture
    private LocalDate date;
}

The ITest:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SpringItest {

    @Autowired
    protected MockMvc mvc;

    @Test
    public void springItest() {
        mvc.perform(MockMvcRequestBuilders
                .post(path)
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestAsJson)
                .andExpect(status().isOk());
    }
}

2 个答案:

答案 0 :(得分:3)

由于@membersound已经提到DateInFutureValidator不是项目的一部分,所以他根本不需要测试DateInFutureValidator。所以我们可以通过使用ClassLoader如何加载类的技巧来禁用它。

如果在测试源目录中有一个具有完全限定名称的类作为库类,ClassLoader将加载它并忽略库类。

package ${package_name_same_as_library_class};

public class DateInFutureValidator implements ConstraintValidator<DateInFuture, Temporal> {
  @Override
  public void initialize(DateInFuture constraintAnnotation) { }

  @Override
  public boolean isValid(Temporal value, ConstraintValidatorContext context) {
    return true;
  }
}

这种方法的缺点是它将全局禁用DateInFutureValidator。但在这种情况下无关紧要,因为它只在集成测试中运行。

答案 1 :(得分:2)

您可以通过提供模拟验证器来实现MockMvc实例的独立设置,这将阻止它执行任何验证。

Validator mockValidator = mock(Validator.class);

MockMvc mockMvc = MockMvcBuilder.standaloneSetup(myController).setValidator(mockValidator);

如果你想做一个你的MockMvc的Web应用程序设置,你正在使用的自动配置的MockMvc实例是这种情况,那么我认为你应该能够通过声明为整个上下文提供一个模拟验证器@MockBean验证器:

@MockBean(name = "mvcValidator")
private Validator mockValidator;