Spring, Junit 에서 session, request scope bean 을 사용하기 

오리대마왕님께서 올려주신 글을 보니 '토비의 스프링 3'에 나오는 웹 테스트 코드가 생각나서 그냥 session 스코프 빈을 한번 등록해 봤습니다. 오리대마왕님 테스트의 주 목적도 이거였을 텐데.. 컨트롤러에 AOP를 등록하고, 현재 request를 담고 있는 HttpRequestHolder를 request 스코프로 만든 걸 봤는데... 테스트 목적에 비해 코드가 다소 장황한 것 같습니다. (사실 올려주신 코드에서 HttpRequestHolder를 request 스코프로 등록하지 않고 그냥 singleton으로 써도 결과는 똑같더군요. 현재 요청을 가로 채고 있던 녀석은 HttpRequestHolder를 request 스코프로 했기 떄문이 아니라 RequestContextHolder 때문인것 같더군요. 그리고 컨트롤러에 설정한 AOP도 그냥 스프링 인터셉터를 쓰시면 더 간단하게.. 처리가 가능한.. 암튼..)
public class SimpleRequestScopeTest {
    @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
    static class RequestScopedBean {}
    @Test
    public void simpleReqestScopeBean() throws ServletException {
        ConfigurableDispatcherServlet dispatcherServlet = new ConfigurableDispatcherServlet();
        dispatcherServlet.setClasses(RequestScopedBean.class);
        dispatcherServlet.init(new MockServletConfig("spring"));
        WebApplicationContext wac = dispatcherServlet.getWebApplicationContext();
        RequestScopedBean rsb = wac.getBean(RequestScopedBean.class);
        assertThat(rsb, is(notNullValue()));
    }
}
이게 다입니다. RequestScopedBean이라는 클래스를 만들고, 스코프를 설정해준 다음 ConfigurableDispatcherSevlet에 전달해서 빈으로 등록해주었고, DS에서 WAC를 가져온다음 RSB를 getBean 해서 null이 아닌지 확인하면 끝입니다.
단순 빈 등록만 확인하려면 WebApplicationContext를 직접 만들어 쓰면 되겠지만, 여기서는 웹 테스트 용도로 작성하는 테스트라고 가정하면, 요청 매핑이나, 실행 결과 ModelAndView등을 확인하려면 역시 DispatcherServlet을 써먹어야 합니다. 하지만 DispatcherServlet은 ModelAndVIew를 밖으로노출해주지 않죠. 그럴 필요도 없구요. 그래서 테스트용으로 DispatcherServlet을 확장한 것이 바로 저기에 보이는 ConfigurableDS입니다. 이 CDS를 사용한 초단단 웹 @MVC 테스트는 다음과 같습니다.
public class HelloControllerTest {
@Test
public void helloController() throws ServletException, IOException {
ConfigurableDispatcherServlet servlet = new ConfigurableDispatcherServlet();
servlet.setRelativeLocations(getClass(), "spring-servlet.xml");
servlet.setClasses(HelloSpring.class);
servlet.init(new MockServletConfig("spring"));
MockHttpServletRequest req = new MockHttpServletRequest("GET", "/hello");
req.addParameter("name", "Spring");
MockHttpServletResponse res = new MockHttpServletResponse();
servlet.service(req, res);
ModelAndView mav = servlet.getModelAndView();
assertThat(mav.getViewName(), is("/WEB-INF/view/hello.jsp"));
assertThat((String)mav.getModel().get("message"), is("Hello Spring"));
}
}
(출처, 토비의 스프링 3 예제 코드)
그러나. 이것 마저도 복잡합니다. ConfigurableDispatcherServlet 를 만들고 설정한 다음, Request에 URL을 설정하고 그 결과로 나오는 MAV를 확인하는 패턴이 고정적입니다. 따라서 이걸 더 간편하게 사용할 수 있도록 만든 클래스가 있는데.. 그게 AbstractDispatcherServletTest 입니다. ConfigurableDispatcherServlet과 AbstractDispatcherServletTest는 토비의 스프링 3에서 직접 보실 수도 있고, 예제 코드를 다운 받아 보실 수도 있는데 설명이 들어있는 책으로 보시는걸 추천해 드립니다.
여기서는 간단한 사용법만 보여드리자면;;
public class SimpleMVCTest extends AbstractDispatcherServletTest {
@Test
public void simpleHandler() throws ServletException, IOException {
this.setClasses(SimpleHandler.class, SimpleViewHandler.class)
.runService("/hi");
assertThat(this.response.getContentAsString(), is("hi"));
this.runService("/view");
assertThat(this.getModelAndView().getViewName(), is("view.jsp"));
}
@Controller static class SimpleHandler {
@RequestMapping("/hi") @ResponseBody 
public String hi() { return "hi"; }
}
@Controller static class SimpleViewHandler {
@RequestMapping("/view")
public String view() { return "view.jsp"; }
}
}
(출처, 토비의 스프링 3 예제 코드)
이런식으로 초간단 MVC 테스트를 만들 수 있습니다.