我需要测试验证注释,但看起来它们不起作用.我不确定JUnit是否也正确.目前,测试将通过,但您可以看到指定的电子邮件地址是错误的.
JUnit的
public static void testContactSuccess() {
Contact contact = new Contact();
contact.setEmail("Jackyahoo.com");
contact.setName("Jack");
System.err.println(contact);
}
Run Code Online (Sandbox Code Playgroud)
要测试的类
public class Contact {
@NotNull
@Size(min = 1, max = 10)
String name;
@NotNull
@Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\."
+"[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@"
+"(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
message="{invalid.email}")
String email;
@Digits(fraction = 0, integer = 10)
@Size(min = 10, max = 10)
String phone;
getters and setters
}
Run Code Online (Sandbox Code Playgroud)
eis*_*eis 62
在对方回答说,"注释不自己做任何事情,你需要使用一个验证器来处理对象"是正确的,然而,答案没有对如何使用验证器实例,这对我来说是这样做的工作指令我真正想要的是什么.
Hibernate-validator是这种验证器的参考实现.您可以非常干净地使用它:
import static org.junit.Assert.assertFalse;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ContactValidationTest {
private Validator validator;
@Before
public void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
public void testContactSuccess() {
// I'd name the test to something like
// invalidEmailShouldFailValidation()
Contact contact = new Contact();
contact.setEmail("Jackyahoo.com");
contact.setName("Jack");
Set<ConstraintViolation<Contact>> violations = validator.validate(contact);
assertFalse(violations.isEmpty());
}
}
Run Code Online (Sandbox Code Playgroud)
这假设您有验证器实现和junit作为依赖项.
使用Maven pom的依赖项示例:
<dependency>
<groupId>org.hibernate</groupId>
<version>5.2.4.Final</version>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
Ooz*_*lly 12
使用以下方法测试验证注释的简单方法javax:
Validator在类级别声明:
private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Run Code Online (Sandbox Code Playgroud)
然后在您的测试中,只需在object您需要验证时调用它,并使用exception您要验证的内容:
Set<TheViolation<TheClassYouAreValidating> violations = validator.validate(theInstanceOfTheClassYouAreValidating);
Run Code Online (Sandbox Code Playgroud)
然后只是assert预期的违规次数:
assertThat(violations.size()).isEqualTo(1);
Run Code Online (Sandbox Code Playgroud)
您需要将此添加到您的依赖项 ( gradle):
compile group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
注释本身不会做任何事情,您需要使用验证器来处理对象。
您的测试需要运行一些这样的代码
Configuration<?> configuration = Validation
.byDefaultProvider()
.providerResolver( new MyResolverStrategy() ) <== this is where is gets tricky
.configure();
ValidatorFactory factory = configuration.buildValidatorFactory();
Contact contact = new Contact();
contact.setEmail("Jackyahoo.com");
contact.setName("Jack");
factory.getValidator().validate(contact); <== this normally gets run in the background by whatever framework you are using
Run Code Online (Sandbox Code Playgroud)
但是,您在这里面临的困难是这些都是接口,您将需要实现才能进行测试。您可以自己实施,也可以找到要使用的。
但是,您想问自己的问题是您要测试什么?That the hibernate validator works the way it should?要么that your regex is correct?
如果这是我,我将认为验证器可以工作(即其他人对此进行了测试),并专注于正则表达式。这将涉及一些反思
public void emailRegex(String email,boolean validates){
Field field = Contact.class.getDeclaredField("email");
javax.validation.constraints.Pattern[] annotations = field.getAnnotationsByType(javax.validation.constraints.Pattern.class);
assertEquals(email.matches(annotations[0].regexp()),validates);
}
Run Code Online (Sandbox Code Playgroud)
然后您可以定义您的testMethods,它们是实际的单元测试
@Test
public void testInvalidEmail() throws NoSuchFieldException {
emailRegex("Jackyahoo.com", false);
}
@Test
public void testValidEmail() throws NoSuchFieldException {
emailRegex("jack@yahoo.com", true);
}
@Test
public void testNoUpperCase() throws NoSuchFieldException {
emailRegex("Jack@yahoo.com", false);
}
Run Code Online (Sandbox Code Playgroud)
首先感谢@Eis的回答,它对我有帮助。这是一个失败测试的好方法,但我想要更多“栩栩如生”的行为。在运行时会抛出异常,所以我想出了这个:
/**
* Simulates the behaviour of bean-validation e.g. @NotNull
*/
private void validateBean(Object bean) throws AssertionError {
Optional<ConstraintViolation<Object>> violation = validator.validate(bean).stream().findFirst();
if (violation.isPresent()) {
throw new ValidationException(violation.get().getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
拥有一个经过验证的实体:
@Data
public class MyEntity {
@NotBlank(message = "Name cannot be empty!")
private String name;
}
Run Code Online (Sandbox Code Playgroud)
在测试中,您可以传递具有无效属性的实例并期望出现异常:
private Validator validator;
@Before
public void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test(expected = ValidationException.class)
public void testValidationWhenNoNameThenThrowException() {
validateBean(new Entity.setName(""));
}
Run Code Online (Sandbox Code Playgroud)
vik*_*kas -1
我认为验证会在调用预定义方法后起作用,这些方法通常由容器完成,大多数情况下不会在调用对象的 setter 之后立即完成。从您共享的文档链接:
> 默认情况下,持久性提供程序将在 PrePersist、PreUpdate 和 PreRemove 生命周期事件发生后立即自动对具有使用 Bean Validation 约束注释的持久字段或属性的实体执行验证。
| 归档时间: |
|
| 查看次数: |
46364 次 |
| 最近记录: |