如何忽略 webservice junit 测试中的验证/ConstraintValidator?
How to ignore a validation / ConstraintValidator in a webservice junit 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
集成测试期间禁用该注释(使用过一段时间的日期)?
spring servlet:
@RestController
public class MyController {
@PostMapping(path)
public Rsp post(MyDTO dto) {
}
}
public class MyDTO {
@NotNull
@DateInFuture
private LocalDate date;
}
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
how to load classes 的技巧来禁用它。
当测试源目录中有一个 class 的完全限定名称为库 class 时,ClassLoader
将加载它并忽略库 class。
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
。但在这种情况下并不重要,因为它 运行 仅在集成测试中。
我有以下简单的网络服务,将来需要 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
集成测试期间禁用该注释(使用过一段时间的日期)?
spring servlet:
@RestController
public class MyController {
@PostMapping(path)
public Rsp post(MyDTO dto) {
}
}
public class MyDTO {
@NotNull
@DateInFuture
private LocalDate date;
}
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
how to load classes 的技巧来禁用它。
当测试源目录中有一个 class 的完全限定名称为库 class 时,ClassLoader
将加载它并忽略库 class。
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
。但在这种情况下并不重要,因为它 运行 仅在集成测试中。