내 콩에 올바른 유효성 검사 주석이 있는지 테스트하려고합니다. 나는 봄 부팅을 사용하고 있습니다. 다음은 테스트 사례의 예입니다.
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;
}
}
}
에 대한 호출 checkIfvalidated()
과를 발생 setSomeProperty(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 자체는 @Validated
있으며 메소드 서명에는 @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);
}
}
테스트 된 콩 :
@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 자체는@Validated
있으며 메소드 서명에는@Valid
Bean이 필요합니다 .
주석 자체는 아무런 의미가 없으며 어떤 방식 으로든 처리되어야합니다. 이 경우 @Validated
주석은 Bean에 대해 Spring 에 의해 처리 됩니다 . 테스트는 Spring 빈이 아니므로 프레임 워크는 평가와 관련된 주석을 보지 않으므로 예외는 없습니다.
테스트가 Spring Bean이더라도 접근 방식은 즉시 작동하지 않을 수 있습니다. 자세한 내용은 이 질문을 참조하십시오.
내 테스트 클래스의 컨텍스트에서 해당 예외를 발생시키는 간단한 방법이 있습니까?
한 번 봐 가지고 이 질문을
서비스 인터페이스의 메서드 서명에 유효성 검사 주석을 사용하면 모든 것이 예상대로 작동합니다. 차이점이 어디인지 모르겠습니다.
이것은 service
스프링 빈 이기 때문에 발생 하지만 테스트는 그렇지 않습니다. 의 메서드 service
가 호출되면에 의해 인터셉트됩니다 MethodValidationInterceptor
. 이는 테스트의 경우가 아닙니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다