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

mem*_*und 5 java junit spring spring-mvc 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Spring Servlet:

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

    }
}


public class MyDTO {
    @NotNull
    @DateInFuture
    private LocalDate date;
}
Run Code Online (Sandbox Code Playgroud)

I测试:

@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());
    }
}
Run Code Online (Sandbox Code Playgroud)

Plo*_*log 5

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

Validator mockValidator = mock(Validator.class);

MockMvc mockMvc = MockMvcBuilder.standaloneSetup(myController).setValidator(mockValidator);
Run Code Online (Sandbox Code Playgroud)

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

@MockBean(name = "mvcValidator")
private Validator mockValidator;
Run Code Online (Sandbox Code Playgroud)


hol*_*ava 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;
  }
}
Run Code Online (Sandbox Code Playgroud)

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