[우아한테크코스] 6월 2일 TIL
[Spring] DTO 검증 테스트
-
mockMvc를 통한 테스트
-
mockito를 통한 mock 객체 생성
-
dto의 검증
기본 설정private static Validator validator; @BeforeAll static void setUp() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); }
검증
@Test @DisplayName("이메일 공백") public void emptyEmail() { TokenRequest tokenRequest = new TokenRequest("", "asdf"); Set<ConstraintViolation<TokenRequest>> violations = validator.validate(tokenRequest); assertTrue(violations.stream() .anyMatch(violation -> violation.getMessage().contains("이메일은 공백이 아닙니다."))); }
검증이 전부 통과하면 set이 empty이고, 통과하지 못하면 violations에 message가 들어있다.
[Spring] @Email vs @Pattern
pattern: @Pattern(regexp = "^[a-zA-Z0-9._%+]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]*$", message = "이메일에는 특수문자가 포함될 수 없습니다.")
email: @없는 것만 확인하고 @ 뒤에 . 오는 것, 아이디에 특수문자가 들어오는 경우에 대해서 처리가 되지 않는다.
pattern을 적용하도록 하자.
[Java] IllegalArgumentException
Thrown to indicate that a method has been passed an illegal or inappropriate argument.
올바르지 않은/적절하지 않은 argument(인자)에 의해서 에러가 발생하는 경우이다.
반면에 RuntimeException의 경우는 아래와 같다.
RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions do not need to be declared in a method or constructor’s throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.
unchecked의 모든 예외를 포괄하고 있는 것이 RuntimeException이다.
적절한 상황에서 상속해서 사용하도록 하자.
[Spring] Validation 사용
Spring Boot의 ValidationAutoConfiguration => LocalValidatorFactoryBean, MethodValidationPostProcessor 설정
- LocalValidatorFactoryBean: Validator 사용
- MethodValidationPostProcessor: parameter, return 값 검증
-
파라미터나 리턴 값 검증을 하려면 클래스 상단에
@Validated
적용
기본적으로 @Controller에는 존재
이렇게 되면 controller뿐만 아니라 모든 클래스에서 사용 가능
붙어있는게 있으면 MethodValidationPostProcessor를 통해 프록시 객체 생성
실제 validation 처리는 MethodValidationInterceptor에서 진행 - @RequestParam, @PathVariable 값 검증에 실패하면
ConstraintViolationException
발생
기본 500 에러, 예외 잡아서 처리 필요
검증에서 준 message를 아래와 같이 활용 가능@ExceptionHandler(value = {ConstraintViolationException.class}) protected ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException e, WebRequest request) { return handleExceptionInternal(e, e.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST, request); }
-
요청 값 검증하려면 @RequestBody 앞에
@Valid
적용
RequestResponseBodyMethodProcessor를 통해 메서드 파라미터 바인딩하는데 여기서 valid, validation도 같이 처리
여기서 에러가 생기면MethodArgumentNotValidException
발생
기본 400에러 -
MessageCodesResolver
spring에서 오류 메시지 코드관리를 위해 사용하는 것
자동으로 설정하는 DefaultMessageCodesResolver가 있고, setMessageCodeFormatter()를 통해 설정 가능 - @Valid와 @Validated 차이
- @Valid: jakarta.validation-api에서 제공
- @Validated: groups 설정 가능