@NotNull, @NotEmpty, @NotBlank 의 차이점
앞서 공통적으로 사용하는 방법 및 예외처리에 대해서 알아봤습니다.
@NotNull & @NotEmpty & @NotBlank 는 사용법은 매우 유사하지만 중요한 차이가 있습니다.
@NotNull
우선 @NotNull 은 위에 살펴본 것 처럼 이름 그대로 Null만 허용하지 않습니다.
따라서, "" 이나 " " 은 허용하게 됩니다.
그렇기 때문에 만약 "" (초기화된 String) )이나 " " (공백) 을 허용하지 않는다면 사용해서는 안됩니다.
Null 이 들어오게 되면, 로직에 예상치 못한 오류가 발생하거나 문제가 생길 경우 사용해야 합니다.
즉, 초기화나 공백의 값이 들어와 저장은 되야하지만 Null 로 들어온 경우 오류가 나는 변수를 받을 때 사용하면 됩니다.
@Test
public void 사용자_이름_DTO_NotNull_체크() {
//given
UserLoginRequestDto user = UserLoginRequestDto.builder()
.name(null)
.email("")
.phone(" ")
.build();
//when
Set<ConstraintViolation<UserLoginRequestDto>> violations = validator.validate(user);
//then
assertThat(violations.size()).isEqualTo(1);
}
name, email, phone 에 모두 @NotNull 이 걸려있다고 가정했을 때,
위의 테스트를 실행하면 통과를 하게됩니다.
name 은 null 이 들어왔기 때문에 violations 에 검증이 되어 잘못된 값이라 판단하여 추가가 되고, email 같은 경우 ""(empty) 는 null 이 아니기 때문에 violations 에 추가되지 않게 됩니다.
phone 의 경우 " "(blank) 이기 때문에 email 과 마찬가지로 null 이 아니기 때문에 violations 에 추가되지 않습니다.
@NotEmpty
@NotEmpty 는 null 과 "" 둘 다 허용하지 않게 합니다.
@NotNull 에서 "" validation 이 추가된 것입니다.
즉, @NotEmpty 는 null 과 "" 은 막히되, " " 은 허용이 됩니다.
@Test
public void 사용자_이름_DTO_NotNull_체크() {
//given
UserLoginRequestDto user = UserLoginRequestDto.builder()
.name(null)
.email("")
.phone(" ")
.build();
//when
Set<ConstraintViolation<UserLoginRequestDto>> violations = validator.validate(user);
//then
assertThat(violations.size()).isEqualTo(2);
}
name, email, phone 에 모두 @NotEmpty 가 걸려있다고 가정했을 때,
위의 테스트를 실행하면 통과를 하게됩니다.
name 은 null 이 들어왔기 때문에 violations 에 검증이 되어 잘못된 값이라 판단하여 추가가 되고, email 같은 경우 ""(empty) 는 ""(empty) 이기 때문에 violations 에 추가가 됩니다.
phone 의 경우 " "(blank) 이기 때문에 null 과 empty 가 아니기 때문에 violations 에 추가되지 않습니다.
@NotBlank
@NotBlank 는 null 과 "" 과 " " 모두 허용하지 않습니다.
@NotEmpty 에서 " " validation 이 추가된 것입니다.
즉, 세개 중 가장 validation 강도가 높은 것으로,@NotBlank 는 null 과 "" 과 " " 모두 허용하지 않습니다.
@Test
public void 사용자_이름_DTO_NotNull_체크() {
//given
UserLoginRequestDto user = UserLoginRequestDto.builder()
.name(null)
.email("")
.phone(" ")
.build();
//when
Set<ConstraintViolation<UserLoginRequestDto>> violations = validator.validate(user);
//then
assertThat(violations.size()).isEqualTo(3);
}
name, email, phone 에 모두 @NotBlank 가 걸려있다고 가정했을 때,
위의 테스트를 실행하면 통과를 하게됩니다.
name 은 null 이 들어왔기 때문에 violations 에 검증이 되어 잘못된 값이라 판단하여 추가가 되고, email 같은 경우 ""(empty) 는 ""(empty) 이기 때문에 violations 에 추가가 됩니다.
phone 의 경우 " "(blank) 이기 때문에 violations 에 추가가 되어 총 3개가 violations 에 추가가되어 성공하게 됩니다 .
결론
앞서 3개의 Bean Validation 의 사용방법, 예외 처리하는 방법, 검증(테스트) 방법에 대해 설명하였습니다.
총 3개의 Validatior 는 사용법과 기능이 유사하기 때문에 쉽게 혼용되거나 잘못 사용될 수 있습니다.
따라서, 해당 DTO 에 대한 테스트를 Validator 에 따라 null , "", " " 에 구분하여 나눠서 추가해야 합니다.
만약, @NotBlank 이어야하는 값이 @NotNull 이 설정되어 공백이 들어오게되면 큰 문제가 발생할 수 있기 때문입니다.
중간에 DTO 를 사용해야하는 이유에 대해서 설명을 드렸습니다.
테스트를 추가할 때도 각 DTO 를 분리하게 되면 각각의 request 에 따라 테스트 코드를 추가해줄 수 있기 때문에 요청을 모두 검증할 수 있어, 테스트 코드에 대한 커버리지가 높아질 수 있습니다.
이처럼 이러한 Validation 을 용도 및 상황에 맞게 사용한다면 사용자의 오류나 시스템의 오류를 최소화 할 수 있습니다.
'Study > SpringBoot' 카테고리의 다른 글
[Gradle] (0) | 2022.06.23 |
---|---|
[Spring Boot] JPA 동적 검색 (QueryDsl) (0) | 2022.05.16 |
Spring-boot JPA 어노테이션 @Entity, @Table, @Column, @Id @Lombok (0) | 2022.05.09 |
스프링부트 시작부터 JSP 설정 실행까지 정리글 (0) | 2022.01.05 |
Entity, DTO, VO 알아보기 (0) | 2021.11.09 |
댓글