Java 如何在webservice junit测试中忽略验证/约束验证器?

Java 如何在webservice junit测试中忽略验证/约束验证器?,java,spring,spring-mvc,junit,spring-test,Java,Spring,Spring Mvc,Junit,Spring Test,我有以下简单的Web服务,将来需要LocalDate。注释为自定义注释,如下所示: @Target({ ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = DateInFutureValidator.class) public @interface DateInFuture { Class<?>[] groups() default {}; Class&l

我有以下简单的Web服务,将来需要
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
    }
}
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());
    }
}

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

Validator mockValidator = mock(Validator.class);

MockMvc mockMvc = MockMvcBuilder.standaloneSetup(myController).setValidator(mockValidator);
如果您想为您的MockMvc进行web应用程序设置,这是您当前使用的自动配置MockMvc实例的情况,那么我认为您应该能够通过声明@MockBean Validator为整个上下文提供一个模拟验证器:

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

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

当在测试源目录中有一个全名为library class的类时,
ClassLoader
将加载它并忽略library类

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;
  }
}
package${package\u name\u same\u as\u library\u class};
公共类DateInputValidator实现ConstraintValidator{
@凌驾
public void initialize(DateInFuture constraintanotation){}
@凌驾
公共布尔值有效(时态值、ConstraintValidatorContext上下文){
返回true;
}
}

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

我认为最好是花点精力使json对象有效(通过使用一个日期,在将来确定),而不是花时间寻找验证旁路。不幸的是,在我的具体情况下,这是不可能的(因为还依赖于不同的模拟Web服务响应、数据库条目等)。将您的
DateInFutureValidator
重新连接到测试源目录下,并使
isValid
始终返回
true
?@holi-java,这样最好。但是如何替换自定义验证器呢?如果测试目录中的类的完整限定符名称与产品类相同,那么将首先加载这些类。你知道我说了什么吗?
@MockBean
奏效了!如果仅仅禁用一个特定的注释是不可能的,我可以接受它。我很高兴听到它!此外,如果加载自定义的
testing.properties
文件,则只需添加以下属性,而不是模拟:
spring.jpa.properties.javax.persistence.validation.mode=none
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;
  }
}