- 문제 발생 개발기록
문제 배경
BoardController
컨트롤러에 대한 테스트 코드를 작성하던 중, 에러가 발생했다.BoardController
클래스의addArticle
메서드에 대한 테스트 작성하던 상태다.- 테스트 코드 작성 완료 후 실행을 했는데, 400 오류가 반환되었다.
BoardController
클래스의addArticle
메서드@PostMapping("/new-article") public String addArticle(@Validated @ModelAttribute("article") NewArticleForm form, @SessionAttribute("loginUser") User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "add-article"; } //로직... return "redirect:/board/1"; }
BoardControllerTest
테스트 클래스의addArticleTest
메서드@DisplayName("게시글 추가") @Test void addArticleTest() throws Exception { //given NewArticleForm wrongForm = new NewArticleForm(); User loginUser = new User(); MockHttpSession session = new MockHttpSession(); wrongForm.setTitle(""); wrongForm.setContent(""); loginUser.setId(5L); loginUser.setName("BoardTestUser"); loginUser.setEmail("BoardTestUser@test.com"); loginUser.setPassword("123test!"); session.setAttribute("loginUser", loginUser); given(boardService.addNewArticle(any())).willReturn(true); //when ResultActions wrongPerform = mockMvc.perform( post("/board/new-article") .param("title", wrongForm.getTitle()) .param("content", wrongForm.getContent()) .session(session) ); //then wrongPerform.andExpect(status().isOk()).andExpect(view().name("add-article")); //validation 실패시 기대 결과 }
- 의도적으로 Bean Validation에 실패하는 요청을 테스트했다.
addArticle
메서드에서 Bean Validation에 실패시,add-article
뷰를 응답하도록 로직 작성하였다.- 하지만, 400 오류가 발생하고 테스트에 실패했다.
Bean Validation에 실패하더라도 200 코드로
add-article
뷰를 응답하도록 작성했는대도 말이다.
- 발생 오류
문제 해결 탐색과정
@WebMvcTest
를 통해, 유닛 테스트를 진행하였다. 그에 따라, 테스트 과정에서 Bean Validation이 제대로 적용되는지 확인하였다.- 그 결과, Bean Validation은 정상 작동한다는 사실을 알았다.
- 실제 로컬에 Web App 실행하여 확인해본 결과, Bean Validation 조건에 일치하지 않는 요청시, 로컬에서도 동일하게 400 오류가 발생했다.
- 따라서, 컨트롤러 메서드의 매개변수 순서가 의심되었다.
문제 해결
문제 원인
BoardController
컨트롤러 클래스의addArticle
메서드의 매개변수가 문제였다.- 해당 메서드의 매개변수 순서는 다음과 같다.
@Validated @ModelAttribute("article") NewArticleForm form
@SessionAttribute("loginUser") User user
BindingResult bindingResult
- 위 순서와 같이 “
@Validated
가 적용된 매개변수”와 “BindingResult 매개변수”가 떨어져서 작성되어 발생하는 문제였다.
BoardController
클래스의addArticle
메서드@PostMapping("/new-article") public String addArticle(@Validated @ModelAttribute("article") NewArticleForm form, @SessionAttribute("loginUser") User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "add-article"; } //로직... return "redirect:/board/1"; }
해결방법
@Validated
매개변수와BindingResult
매개변수를 아래 순서와 같이 작성한다.@Validated
매개변수BindingResult
매개변수
- 항상
@Validated
바로 뒤에BindingResult
매개변수가 와야한다. - 예시
BoardController
클래스의addArticle
메서드@PostMapping("/new-article") public String addArticle(@SessionAttribute("loginUser") User user, @Validated @ModelAttribute("article") NewArticleForm form, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "add-article"; } //로직... return "redirect:/board/1"; }