ode*_*dia 5 java validation hibernate-validator bean-validation
我有一个特定的场景,在该场景中,稍后只能手动检查违规情况。
我想做的是抛出一个ConstraintViolationException,并为其提供“真实” ConstraintViolation object(当我将异常捕获到堆栈中时,我使用#{validatedValue}和violation.getPropertyPath()参数)。
如何在ConstraintViolation没有框架的情况下通过注释为我创建自己(我使用Hibernate Validator)?
代码示例:
List<String> columnsListForSorting = new ArrayList<String>(service.getColumnsList(domain));
Collections.sort(columnsListForSorting);
String firstFieldToSortBy = this.getTranslatedFieldName(domain.getClass().getCanonicalName(), sortingInfo.getSortedColumn());
if (!columnsListForSorting.contains(firstFieldToSortBy)){
throw new ConstraintViolationException(<what here?...>);
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
我不喜欢 Hibernate Validator 的另一个原因。当它应该非常简单时,它们使得以编程方式创建简单的违规变得非常困难。我确实有测试代码,我需要在其中创建违规以提供给我的模拟子系统。
无论如何,没有滚动您自己的违规约束实现 - 这是我为字段创建违规所做的工作:
private static final String MESSAGE_TEMPLATE = "{messageTemplate}";
private static final String MESSAGE = "message";
public static <T, A extends Annotation> ConstraintViolation<T> forField(
final T rootBean,
final Class<T> clazz,
final Class<A> annotationClazz,
final Object leafBean,
final String field,
final Object offendingValue) {
ConstraintViolation<T> violation = null;
try {
Field member = clazz.getDeclaredField(field);
A annotation = member.getAnnotation(annotationClazz);
ConstraintDescriptor<A> descriptor = new ConstraintDescriptorImpl<>(
new ConstraintHelper(),
member,
annotation,
ElementType.FIELD);
Path p = PathImpl.createPathFromString(field);
violation = ConstraintViolationImpl.forBeanValidation(
MESSAGE_TEMPLATE,
MESSAGE,
clazz,
rootBean,
leafBean,
offendingValue,
p,
descriptor,
ElementType.FIELD);
} catch (NoSuchFieldException ignore) {}
return violation;
}
Run Code Online (Sandbox Code Playgroud)
HTH
在我看来,最简单的方法是模拟您的服务以在测试中抛出约束违规。例如,您可以通过扩展类来手动完成此操作,也可以使用模拟框架(例如mockito ) 。我更喜欢模拟框架,因为它们大大简化了事情,因为您不必创建和维护额外的类,也不必将它们注入到被测试的对象中。
以mockito为起点,您可能会编写类似以下内容的内容:
import org.hibernate.exception.ConstraintViolationException;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.mockito.Mockito.when;
public class MyTest {
@Mock /* service mock */
private MyService myService;
@InjectMocks /* inject the mocks in the object under test */
private ServiceCaller serviceCaller;
@Test
public void shouldHandleConstraintViolation() {
// make the mock throw the exception when called
when(myService.someMethod(...)).thenThrow(new ConstraintViolationException(...))
// get the operation result
MyResult result = serviceCaller.doSomeStuffWhichInvokesTheServiceMethodThrowingConstraintViolation();
// verify all went according to plan
assertWhatever(result);
}
}
Run Code Online (Sandbox Code Playgroud)
这里有几件事:
ConstraintViolation是一个接口,因此您可以实现自己的版本
Hibernate Validator 使用该接口自己的内部实现 - org.hibernate.validator.internal.engine.ConstraintViolationImpl。它是一个公共类,但由于它位于内部包中,因此不鼓励您直接使用它。但是,您可能会了解实现ConstraintViolation需要什么。
| 归档时间: |
|
| 查看次数: |
12255 次 |
| 最近记录: |