본문 바로가기

Java/Spring

spring mvc 단위테스트

spring 3.2 부터 사용가능한 mockMvc이 활용된 단위테스트입니다.

간단한 로그인으로 가정합니다. 

html

아이디와 비밀번호를 넣고 로그인하는 화면입니다.

<form action="/user/login" method="post">
    <input type="text" name="userId">
    <input type="password" name="userPw">
    <input type="submit" value="로그인">
</form>
cs

controller

일치하는 정보 없으면 / 로 넘기고 있으면 다음 페이지로 넘어가게만 처리했습니다. 
@Controller
@RequestMapping("/user/*")
public class UserController {
    
    @Autowired
    private UserService service;
    
    @PostMapping("/login")
    public String login(
            @RequestParam("userId"String userId,
            @RequestParam("userPw"String userPw, HttpSession session) {
        Map<StringString> map = new HashMap<>();
        map.put("userId", userId);
        map.put("userPw", userPw);
        UserVO user = service.login(map);
        
        if(user == null) {
            return "redirect:/";
        }
        session.setAttribute("user", user);
        return "redirect:/main";
    }
}
cs

test

아래 테스트는 로그인 화면에서 아이디 test, 비밀번호 test를 입력하고 submit 한 것이죠. 
로그인이 성공했다면 redirect:/main 이 찍히게 됩니다. 실패하면 redirect:/ 가 찍히겠네요. 

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
@Log4j
@WebAppConfiguration
public class UserControllerTests {
    
    @Autowired
    private WebApplicationContext wac;
    
    private MockMvc mockMvc;
    
    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }
    
    @Test
    public void login() throws Exception {
        log.info(mockMvc.perform(MockMvcRequestBuilders.post("/user/login")
                        .param("userId""test")
                        .param("userPw""test"))
                        .andReturn().getModelAndView().getViewName());
    }
 
}
cs


Model 객체를 전달하고 있다면 getViewName() 대신 getModelMap() 을 사용하실 수 있구요

RedirectAttributes 의 flash attribute를 사용중이라면 getModelAndView() 대신 getFlashMap()을 사용할 수 있습니다.


만약 응답형태가 json이라면 아래를 참고하세요. 

https://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-write-clean-assertions-with-jsonpath/

session

만약 세션 객체를 테스트에서 다루고 싶다면 아래와 같이 해볼 수 있습니다. 
위에서 설정했던, 로그인을 성공하면 들어가는 /main 페이지에 인터셉터가 걸려있다고 생각해 봅시다.
(유저 세션이 없다면 / 로 튕겨져 나가는) 

단순히 get("/main") 으로 테스트하면 테스트가 실패하게 됩니다. 
인터셉터때문에 세션이 없으면 /main 에 진입하지 못하기 때문입니다. 
따라서 아래와 같이 테스트하셔야 됩니다.

@Test
public void home() throws Exception {
    Map<String, Object> sessionAttributes = new HashMap<>();
    sessionAttrs.put("user", service.findByUserId("test"));
    
    log.info(mockMvc.perform(get("/main").sessionAttrs(sessionAttributes))
                    .andReturn().getModelAndView().getViewName());
}
cs