当前位置: 首页 > 知识库问答 >
问题:

如何使用JUnit测试类的验证注释?

夏侯鹏
2023-03-14

我需要测试验证注释,但看起来它们不起作用。我不确定JUnit是否也是正确的。目前,测试将通过,但您可以看到指定的电子邮件地址是错误的。

JUnit

public static void testContactSuccess() {
        Contact contact = new Contact();
        contact.setEmail("Jackyahoo.com");
        contact.setName("Jack");
        System.err.println(contact);
    }

待测试类别

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

}

共有3个答案

邢飞鸿
2023-03-14

注释本身不做任何事情,您需要使用Validator来处理对象。

您的测试需要运行以下代码

    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

然而,您在这里面临的困难是这些都是接口,您需要实现才能进行测试。您可以自己实现它,也可以找一个来使用。

然而,你想问自己的问题是,你想测试什么<代码>hibernate验证器的工作方式应该是什么

如果这是我,我会假设Validator工作(即其他人测试过)并专注于正则表达式。这将涉及一些反思

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);

}

然后您可以定义您的测试方法,这些方法是实际的单元测试

@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);
}
颛孙嘉石
2023-03-14

使用javax测试验证注释的一种简单方法:

在类级别声明验证器:

private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

然后,在测试中,只需在需要验证的对象上调用它,就可以验证什么异常:

Set<TheViolation<TheClassYouAreValidating> violations = validator.validate(theInstanceOfTheClassYouAreValidating);

然后简单地断言预期违规的数量:

assertThat(violations.size()).isEqualTo(1);

您需要将此项添加到依赖项中(gradle):

编译组:'javax.validation',名称:'vality-api',版本:'2.0.1。最终'

阙博容
2023-03-14

另一个答案说“注释本身不做任何事情,您需要使用Validator来处理对象”是正确的,但是,这个答案缺乏关于如何使用Validator实例进行操作的工作说明,这对我来说是我真正想要的。

Hibernate验证器是此类验证器的参考实现。您可以像这样干净地使用它:

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());
    }
}

这假设您有验证器实现和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>
 类似资料:
  • 我有一组实体类,它们是由Hibernate工具生成的。都有@列注释,如: 我想编写一个JUnit测试来验证我对数据库的输入,但JUnit验证只在添加以下内容时有效: 我不希望添加任何注释,因为这样我需要更改自动生成的实体类。如何让JUnit测试使用第一个生成的@列注释?谢谢 我的JUnit测试(不适用于仅@列,但适用于额外的@NotNull和@size): 公共类CountryEntityTest

  • 问题内容: 我想对用Apache CXF编写的RESTful接口进行单元测试。 我使用ServletContext来加载一些资源,所以我有: 如果我将其部署在Glassfish上,则会注入ServletContext,并且它会按预期工作。但是我不知道如何将ServletContext注入我的服务类中,以便可以使用JUnit测试对其进行测试。 我使用Spring 3.0,JUnit 4,CXF 2.

  • 我是java新手,我正在编写一个ATM程序,用户可以输入三次pin码,如果他们输入的pin码不正确,他们的卡就会被阻塞。我曾尝试为以下代码编写Junit测试,但似乎无法理解。我有两门课,分别是AtmPin和AtmTester。AtmTester是主类所在的位置。 AtmPin.java AtmTester.java

  • 我需要对使用WebClient的类进行单元测试。有什么好方法来处理网络客户端吗?有了RestTemplate,我可以很容易地使用Mockito。模拟WebClient有点乏味,因为深度存根不适用于WebClient。。。 我想测试我的代码是否提供了正确的头。。。缩短的样本代码:

  • 我有一个使用javax注释的jax-rs项目(

  • 我想为我的一个编写一个简单的测试,并断言输入已正确映射到: 问题:如何向该servlet发送请求正文。然后再检查一下字段是否都设置正确? 这可能与此类似,但我不知道如何检查/监视已解析的DTO? @重复标记:这不是链接问题(关于如何读取响应正文字符串)的重复。我实际上是在要求进行身体测试。