我需要在我的自定义ConstraintValidator上进行验证,它使用了一些验证所需的@Inject,就像夸库的这个例子https://quarkus.io/guides/validation
@ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
@Inject
MyService service;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return service.validate(value);
}
}
当我运行应用程序时,我看到这是正确的验证,但我试图使用mockito进行单元测试,我无法使用默认Bean验证在默认值上模拟对象始终为空。
在夸克的例子中,单元测试仅用于集成。
这是我的实现
@ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
@Inject
BookService service;
@ConfigProperty(name = "my.property")
int myLimit;
public MyConstraintValidator(BookService service) {
this.service = service;
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
System.out.println("myLimit property: " + myLimit);
int limit = Integer.parseInt(value);
if (limit < myLimit) {
return service.validate(value);
} else {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(NAME_EMPTY).addConstraintViolation();
return false;
}
}
}
用于测试自定义Validator的单元测试
@Test
void testAmountValidationWithContext() {
BookRequest bookRequest = new BookRequest();
bookRequest.setTitle("my title");
bookRequest.setAuthor("my Author");
bookRequest.setPages(2L);
bookRequest.setAmount("11");
//when:
myConstraintValidator = new MyConstraintValidator(service);
Mockito.when(service.validate(anyString())).thenReturn(true);
//then:
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);
// verify that the context is called with the correct argument
Mockito.verify(context).buildConstraintViolationWithTemplate(NAME_EMPTY);
}
单元测试默认@NoBlank。
@Test
void testBeanValidationWithInvalidAmount() {
BookRequest bookRequest = new BookRequest();
bookRequest.setTitle("my title");
bookRequest.setAuthor("my Author");
bookRequest.setPages(2L);
bookRequest.setAmount("AA");
//when:
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);
//then:
assertEquals(1, violations.size());
assertEquals(NOT_EMPTY, violations.stream().findFirst().get().getMessage());
}
第一单元测试工作得很好,我可以模拟对象并测试结果。
问题出在我的第二个测试中,当我尝试测试其他验证@NotNull,@Pattern时。在这个测试中,方法isValid()也被调用,这是我的问题,因为@ConfigProperty和@Inject总是空的,我无法模拟它们。
我已经在互联网上看到了几个例子,但不起作用,几乎是Spring,但我需要在夸克斯上进行自定义验证。
我如何实现自定义ConstraintValidator单元测试使用夸克?
有人有这样工作的例子吗?
将代码从字段注入更改为构造函数注入将使单元测试变得更加容易。
@ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
private final MyService service;
private final int myLimit;
public MyConstraintValidator(MyService service, @ConfigProperty(name = "my.property") int myLimit) {
this.service = service;
this.myLimit = myLimit;
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
if (value == null) {
return true;
}
return service.validate(value);
}
}
用我的实现更新了描述。但是继续这个问题。当我有我的自定义验证器的默认注释时,我不能使用
设置