이번 포스트에서는 @Controller에 대한 다양한 테스트 예를 살펴보자.
@Controller에 대한 다양한 단위테스트 처리해보기
먼저 테스트 대상인 @Controller와 테스트를 구성해보자.
@Controller
public class MainController {
@GetMapping("/")
public String index() {... }
@GetMapping("/redirect")
public String redirect(RedirectAttributes redirAttr) {... }
@GetMapping("/add")
public String add(@RequestParam double a, @RequestParam double b, @CookieValue(required = false) String name, Model model) {... }
@PostMapping(value = "/onlypost")
public String onlyPost(Model model) {... }
@GetMapping(value = "/dto")
public String useDto(@ModelAttribute Board board, Model model) {... }
@GetMapping(value = "/cookieSession")
public String cookieAndSession(@CookieValue String name, HttpSession session, Model model, HttpServletResponse res) {... }
}
테스트는 위 MainController만을 대상으로 삼아서 진행한다.
@WebMvcTest({ MainController.class })
public class T_9315_WebMvcTest {
@Autowired
MockMvc mockMvc;
}
@RequestParam과 @Cookie 전달 처리
Controller
@GetMapping("/add")
public String add(@RequestParam double a, @RequestParam double b,
@CookieValue(required = false) String name, Model model) {
model.addAttribute("result", a + b);
model.addAttribute("name", name);
return "showMessage";
}
테스트
@Test
@DisplayName("파라미터와 쿠키를 이용해서 요청을 생성하고 handler, model, view, status 검증")
public void addTest() throws Exception {
// given
String url = "/add";
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("a", "10");
map.add("b", "20");
Cookie nameCookie = new Cookie("name", "홍길동");
// when
MockHttpServletRequestBuilder builder = get(url).params(map).cookie(nameCookie);
ResultActions result = mockMvc.perform(builder);
// then
result.andExpect(handler().handlerType(MainController.class))
.andExpect(handler().methodName("add"))
.andExpect(model().attribute("result", Double.valueOf(30.0)))
.andExpect(view().name("showMessage"))
.andExpect(status().isOk())
.andDo(print());
}
redirect되는 상황에 대한 검증
Controller
@GetMapping("/redirect")
public String redirect(RedirectAttributes redirAttr) {
redirAttr.addAttribute("queryStr1", "hello");
redirAttr.addFlashAttribute("flash1", 100);
return "redirect:/";
}
테스트
@Test
public void redirectTest() throws Exception {
// given
String url = "/redirect";
// when
ResultActions result = mockMvc.perform(get(url));
// then
result.andExpect(handler().handlerType(MainController.class))
.andExpect(handler().methodName("redirect"))
.andExpect(view().name("redirect:/"))
.andExpect(redirectedUrl("/?queryStr1=hello"))
.andExpect(flash().attribute("flash1", 100))
.andExpect(status().is(302)) // redirect 구성
.andDo(print());
}
특정 HttpMethod만 지원하는 상황에 대한 검증
Controller
@PostMapping(value = "/onlypost")
public String onlyPost(Model model) {
model.addAttribute("result", "post만 지원");
return "index";
}
테스트
@Test
public void methodTest() throws Exception {
// given
String url = "/onlypost";
// when
ResultActions result = mockMvc.perform(get(url));
// then : get으로 호출한 경우 405 오류가 발생해야 한다. 4XX로 퉁친다
result.andExpect(status().is(405))
.andExpect(status().is4xxClientError());
// when
result = mockMvc.perform(post(url));
// then: get으로 호출한 경우 405 오류가 발생해야 한다. 4XX로 퉁친다
result.andExpect(status().isOk());
}
세션 값 검증
Controller
@GetMapping(value = "/session")
public String cookieAndSession(HttpSession session, Model model, HttpServletResponse res) {
model.addAttribute("result", "session test");
model.addAttribute("echoSession", session.getAttribute("age"));
session.setAttribute("setSession", "seoul");
res.addCookie(new Cookie("setCookie", "율도국왕"));
return "index";
}
테스트
@Test
public void testCookieSession() throws Exception {
// given
String url = "/session";
int age = 30;
// when
ResultActions result = mockMvc.perform(get(url).sessionAttr("age", age));
// then
MvcResult mvcResult = result.andExpect(status().is(200)).andDo(print()).andReturn();
HttpSession session = mvcResult.getRequest().getSession();
assertEquals(session.getAttribute("setSession"), "seoul");
Map<String, Object> model = mvcResult.getModelAndView().getModel();
assertEquals(model.get("echoSession"), age);
MockHttpServletResponse res = mvcResult.getResponse();
assertEquals(res.getCookie("setCookie").getValue(), "율도국왕");
}