작성
·
239
·
수정됨
0
안녕하십니까. 데이터 검증2 를 듣다가 궁금한점이 생겨서 질문을 남기게 되었습니다.
@Getter
@RequiredArgsConstructor
public class ErrorResponse {
private final String code;
private final String message;
private final List<Validation> validations = new ArrayList<>();
public void addValidation(String fieldName, String errorMessage) {
this.validations.add(new Validation(fieldName, errorMessage));
}
private record Validation(String fieldName, String errorMessage) {
}
}
@Test
@DisplayName("/posts 요청시 title 값 필수.")
void test2() throws Exception {
mockMvc.perform(post("/posts")
.contentType(MediaType.APPLICATION_JSON)
.content("{}")
)
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.code").value("400"))
.andExpect(jsonPath("$.message").value("잘못된 요청입니다."))
.andExpect(jsonPath("$.validations[0].errorMessage").value("title을 입력해주세요."))
.andExpect(jsonPath("$.validations[1].errorMessage").value("content를 입력해주세요."))
.andDo(print());
}
일단 Map -> List<Validation> 방식으로 수정해보았는데요
@Setter
@Getter
@ToString
public class PostCreate {
@NotBlank(message = "title을 입력해주세요.")
private String title;
@NotBlank(message = "content를 입력해주세요.")
private String content;
}
테스트 코드에서 0번째 에러메시지가 title을 입력해주세요
가 될 줄 알았는데 content를 입력해주세요
가 나와서 실패했습니다. (PostCreate 필드 순서대로 validations에 담길 줄 알았는데 예상되로 나오지 않았습니다.) -> 테스트 할 때마다 결과가 뒤죽박죽 이네요. 이러한 경우 어떻게 테스트 하는지 궁금합니다.
또한 이렇게 만약 여러 error field가 잡히거나, 에러 메시지가 바뀌는 경우가 생기면 테스트 코드 수정이 빈번해 질 것 같은데 어떻게 해결할 수 있을지 궁금합니다.
마지막으로 List<Validation> 방법 말고 조금 더 많이 쓰이는 ? 혹은 괜찮은 방법 있으면 추천해주시면 감사하겠습니다.
답변 1
1
안녕하세요, 인프런 AI 인턴입니다.
jorongting님의 질문에 답변 드리겠습니다.
Spring Boot에서 Bean Validation을 이용하여 요청 파라미터 검증 시, 검증 순서가 고정되지 않아 테스트가 일관되지 않는 문제에 대해 고민이 되신 것 같습니다.
이 문제는 자바 리플렉션 API가 클래스의 멤버를 반환할 때, 멤버의 순서가 일정하지 않음으로 발생할 수 있습니다. 때문에, 에러가 일어난 순서에 의존하는 테스트 코드는 안정적이지 않을 수 있습니다.
테스트가 일관되도록 하기 위한 방법으로, 에러 메시지를 검증할 때 인덱스(예: .validations[0].errorMessage
)를 사용하는 대신에, 특정 에러 메시지가 존재하는지 여부만을 확인하는 방향으로 테스트를 작성하는 것을 고려할 수 있습니다.
에러 메시지의 내용이 변경될 때 테스트 코드를 빈번하게 수정하는 문제를 해결하기 위하여, 에러 메시지를 상수로 관리하거나 외부 메시지 소스(messages.properties
)에서 관리하여 사용하시는 것이 좋습니다.
List<Validation>
방법 외에도 Map<String, String>
방식을 사용하면 필드명과 메시지를 더 직관적으로 관리할 수 있고, JSON 응답으로 필드 에러 정보를 클라이언트에 전달할 때 필드명을 키로 사용하면 된다는 장점이 있습니다. 하지만, 에러 필드가 중복될 경우에는 적합하지 않을 수 있습니다.
필드별로 정렬된 에러 메시지를 보장하고자 한다면 커스텀 검증 로직을 사용하여 에러 정보를 필드 순서에 맞게 정렬하여 반환하는 로직을 추가하는 방법도 있습니다.
마지막으로, Spring Boot 2.3 이후 버전부터는 MethodValidationPostProcessor
를 사용하여 메소드 레벨의 검증을 커스터마이징할 수 있습니다. 더 많은 정보는 Spring Boot Reference Documentation - Validation에서 확인하실 수 있습니다.
정확한 해결책을 찾으시려면 실제 애플리케이션의 구조와 요구사항을 고려하여 적합한 방법을 선택하시는 것이 중요합니다. 개발 환경과 요구사항에 맞추어 가장 효율적인 방법을 찾아 적용하시길 바랍니다.
답변 감사합니다.