我正在尝试测试我的bean是否具有正确的验证注释。我正在使用sping-boot。这是一个示例测试用例:
package com.example.sandbox;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.validation.annotation.Validated;
@SpringBootTest
class ValidationTest {
@Test
void testConstructor() {
TestedBean bean = new TestedBean(null);
assertThatThrownBy(() -> checkIfValidated(bean)).isInstanceOf(ConstraintViolationException.class);
}
@Test
void testSetter() {
TestedBean bean = new TestedBean(null);
assertThatThrownBy(() -> bean.setSomeProperty(null)).isInstanceOf(ConstraintViolationException.class);
}
private void checkIfValidated(@Valid TestedBean bean) {
}
@Validated
class TestedBean {
@NotNull
private String someProperty;
public TestedBean(String someProperty) {
super();
this.someProperty = someProperty;
}
public String getSomeProperty() {
return someProperty;
}
public void setSomeProperty(@NotNull String someProperty) {
this.someProperty = someProperty;
}
}
}
我希望调用check Ifvalated()
和setSymProperty(null)
以引发ConstraintViolationException
,并通过测试,但它们都失败了:
java.lang.AssertionError:
Expecting code to raise a throwable.
at com.example.sandbox.ValidationTest.test(ValidationTest.java:20)
...
我的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>com.example.springbootsandbox</artifactId>
<version>0.0</version>
<name>SpringBootSandbox</name>
<description>Sandbox for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
为什么这里没有引发ConstraintViolationException
?bean属性有一个@NotNull
注释,bean本身是@Valated
并且方法签名需要一个@Valid
bean。
有没有一种简单的方法可以在测试类的上下文中引发该异常?
当我在服务接口的方法签名上使用验证注释时,一切都按预期工作。我不明白区别在哪里。
服务接口:
package com.example.sandbox;
import javax.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
@Validated
public interface IService {
public void setValue(@NotNull String value);
}
服务实施:
package com.example.sandbox;
import org.springframework.stereotype.Service;
@Service
public class SomeService implements IService {
@Override
public void setValue(String value) {
// Do nothing
}
}
测试用例:
package com.example.sandbox;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import javax.validation.ConstraintViolationException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SomeServiceTests {
@Autowired
IService service;
@Test
void testSetValue() {
assertThatThrownBy(() -> service.setValue(null)).isInstanceOf(ConstraintViolationException.class);
}
}
==
根据给定答案的工作代码:
测试类别:
@SpringBootTest
class ValidationTest {
@Autowired
private Validator validator; // Using the default validator to test property annotations
@Autowired
private TestedBeanService service; // Using a service to test method annotations
@Test
void testPropertyAnnotations() {
TestedBean bean = new TestedBean(null);
Set<ConstraintViolation<TestedBean>> violations = validator.validate(bean);
assertThat(violations).isNotEmpty();
}
@Test
void testMethodAnnotations() {
TestedBean bean = new TestedBean(null);
assertThatThrownBy(() -> service.setBeanProperty(bean, null)).isInstanceOf(ConstraintViolationException.class);
}
}
测试bean:
@Validated
class TestedBean {
@NotNull
private String someProperty;
public TestedBean(String someProperty) {
super();
this.someProperty = someProperty;
}
public String getSomeProperty() {
return someProperty;
}
public void setSomeProperty(String someProperty) { // No more annotation on setter
this.someProperty = someProperty;
}
}
服务接口:
@Validated
public interface TestedBeanService {
// method annotation on the interface method
void setBeanProperty(TestedBean bean, @NotNull String someProperty);
}
服务实现:
@Service
public class TestedBeanServiceImpl implements TestedBeanService {
@Override
public void setBeanProperty(TestedBean bean, String someProperty) {
bean.setSomeProperty(someProperty);
}
}
为什么这里没有引发ConstraintViolationException
?bean属性有一个@NotNull
注释,bean本身是@Valated
并且方法签名需要一个@Valid
bean。
注释本身并不意味着什么,它们应该以某种方式进行处理。在这种情况下,Spring将为其bean处理经过验证的注释。测试不是Springbean,因此框架不会查看与valdidation相关的注释,因此也不例外。
即使测试是Spring Bean,这种方法也可能无法开箱即用。有关详细信息,请参阅此问题。
有没有一种简单的方法可以在测试类的上下文中引发该异常?
看看这个问题
当我在服务接口的方法签名上使用验证注释时,一切都按预期工作。我不明白区别在哪里。
这是因为服务是Spring bean,而测试不是。当调用服务上的方法时,它会被MethodValidationInterceptor截获,而这不是测试的情况
我需要测试验证注释,但看起来它们不起作用。我不确定JUnit是否也是正确的。目前,测试将通过,但您可以看到指定的电子邮件地址是错误的。 JUnit 待测试类别
假设我有以下课程: 是否可以通过“MyProduct”类验证“code”属性?比如:
我们正在开发REST服务,并希望使用JSR303进行输入数据验证,但这里的问题是所有模型对象都是从groovy DSL生成的,并将作为jars导入。因此,在对象字段之上编写JSR-303注释没有灵活性。 那么,有没有其他方法可以不用注释使用JSR-303,可以通过XML配置吗?或者在这种情况下,请提供任何验证建议。 谢啦
使用Springboot 2.5.7和捆绑的Junit5(通过spring boot starter测试),我试图通过定制的标准注释测试我在整个bean中设置的约束。 我找到的大多数留档都是关于jit4的,我找不到一种方法让它在springboot5中工作。 另外,我有点困惑,因为在理想情况下,我想测试每个约束的containt,并且只找到关于如何全局测试它的文档(使用junit4)。 有人已经摆
阅读JSR-303的规范: initialize方法由Bean验证提供程序在使用约束实现之前调用。 每次验证给定值时,isValid方法由Bean验证提供程序评估。如果值无效,则返回false,否则返回true。isValid实现必须是线程安全的。 我不太明白。initialize在每次isValid调用之前调用,isValid应该是线程安全的?这是否意味着我不能在initialize中存储类级别
由于某种原因,当我单独使用@ComponentScan时,我的DAO没有加载。 我的道: 我的配置类(用嵌入的数据库覆盖数据源bean): 我的测试课: 我的理解是@ComponentScan应该能够找到MyDAO并加载它(TestConfig类中的数据源加载得很好)。但是,没有加载MyDAO。我得到了“org.springframework.beans.factory.NoSuchBeanDef