Jersey 自定义验证器单元测试

Che*_*gan 5 validation unit-testing jersey

我有一个用 Jersey 和 Spring-Boot 编写的 REST 服务。我已经为 POST 参数编写了自定义验证器类。我想单元测试相同。我不知道该怎么做。我的验证器如下所示:

@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidTaskForCreate.Validator.class)
public @interface ValidTaskForCreate {
     String message() default "Invalid Request to create a Task";
     Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
public class Validator implements ConstraintValidator<ValidTaskForCreate, Task> {

    @Override
    public void initialize(ValidTaskForCreate constraintAnnotation) {
    }

    @Override
    public boolean isValid(final Task task, ConstraintValidatorContext context) {
            context.disableDefaultConstraintViolation();
            if(task.getName() == null || task.getName().isEmpty()) {
                context.buildConstraintViolationWithTemplate("Task name should be specified").addConstraintViolation();
                return false;
            }

            if(task.getTaskType() == null)  {       
                context.buildConstraintViolationWithTemplate("Specify a valid TaskType in the range of [1..3]").addConstraintViolation();
                return false;
            }
            return true;
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想通过传递各种 Task 对象来测试 isValid() 函数。我现在不确定如何调用此方法。我可以像这样创建 Validator 类的实例,

    ValidTaskForCreate.Validator taskValidator = null;
    taskValidator = new ValidTaskForCreate.Validator();
Run Code Online (Sandbox Code Playgroud)

要调用 isValid(),我可以使用 taskValidator.isValid()。但我不知道如何创建 ConstraintValidatorContext 对象作为第二个参数传递。

或者有什么方法可以像这样 UnitTest 自定义验证类?

Pau*_*tha 7

但我不知道如何创建 ConstraintValidatorContext 对象作为第二个参数传递。

只需使用Mockito并模拟它。然后只需验证是否调用了正确的方法。这是在涉及依赖项时测试单元行为的方法。

private ConstraintValidatorContext context;
private ConstraintValidatorContext.ConstraintViolationBuilder builder;
    
@Before
public void setup() {
    // mock the context
    context = Mockito.mock(ConstraintValidatorContext.class);

    // context.buildConstraintViolationWithTemplate returns
    // ConstraintValidatorContext.ConstraintViolationBuilder
    // so we mock that too as you will be calling one of it's methods
    builder = Mockito.mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
    
   // when the context.buildConstraintViolationWithTemplate is called,
   // the mock should return the builder.
    Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()))
            .thenReturn(builder);
}
    
@Test
public void test() {
    // call the unit to be tested
    boolean result = ..isValid(badTask, context);
    
    // assert the result
    assertThat(result).isFalse();

    // verify that the context is called with the correct argument
    Mockito.verify(context)
            .buildConstraintViolationWithTemplate("Task name should be specified");
}
Run Code Online (Sandbox Code Playgroud)

注意Mockito直接使用。在大多数情况下,您可能只会使用静态导入来减少冗长。我只是想让它更具可读性