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