컨트롤러의 주된 목적은 handleRequest안에 Request와 Respnse 객체를 넣어서 결국 ModelAndView 객체를 반환하는 것입니다.

사용자 삽입 이미지따라서 다음과 같은 결론을 조심스래 내놓을 수 있습니다.

Controller 테스트 ==
ModelAndView
테스트

아직은 TDD에 익숙하지도 않고 테스트 클래스를 어떻게 작성해야 할지도 모르기 때문에;; 일단은 구현을 하고 그 것을 테스트 하는 방법을 익히는 식으로 공부하고 있습니다.

먼저 Controller 하나를 구현합니다.

public class CheckController extends SimpleFormController {

    private MemberService memberService;

    public CheckController() {
        setCommandClass(MemberCommand.class);
        setCommandName("memberCommand");
        setFormView("check");
        setSuccessView("confirm");
    }

    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }

    @Override
    protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException exception) throws Exception {
        MemberCommand memberCommand = (MemberCommand)command;
        Member member = memberService.findByMail(memberCommand.getMail());
        if(member != null)
            return new ModelAndView(getSuccessView())
                .addObject("member", member);
        else
            return new ModelAndView("redirect:join.html");
    }
}

이 컨트롤러는 입력 받은 mail 주소를 사용하여 DB에서 검색을 하여 있으면 confirm 페이지로 없으면 join 페이지로 리다이렉션하는 컨트롤러 입니다.

이것을 테스트 하려면 다음과 같이 if 조건문에 걸릴 경우(true)와 걸리지 않는 경우(false)를 모두 테스트 해봐야 합니다. 이 때 테스트 할 것은 위에서도 말했지만 결국은 ModelAndView입니다.

JUnit의 TestCase를 직접 사용해도 되지만 spring-mock.jar 에 Spring 2.0에서 추가된 AbstractModelAndViewTests 클래스를 사용하여 다음과 같이 테스트를 할 수 있습니다.

public class CheckControllerTest extends AbstractModelAndViewTests{

    private CheckController controller;
    private MockHttpServletRequest request;
    private MockHttpServletResponse response;
    private MemberService mockMemberService;
    private String mail;

    public void setUp() {
        request = new MockHttpServletRequest();
        response = new MockHttpServletResponse();
        mockMemberService = createMock(MemberService.class);
        controller = new CheckController();
        controller.setMemberService(mockMemberService);
    }

    public void testEmptyOrWhiteMail() throws Exception {
        mail = "";
        expect(mockMemberService.findByMail(mail)).andReturn(null);
        replay(mockMemberService);
        request.addParameter("mail", mail);
        request.setMethod("POST");
        ModelAndView mav = controller.handleRequest(request, response);
        assertEquals("redirect:join.html", mav.getViewName());
        assertViewName(mav, "redirect:join.html");
        verify(mockMemberService);
    }

    public void testExistMemberMail() throws Exception {
        Member member = new Member();
        mail = "keesun@mail.com";
        member.setMail(mail);
        member.setName("기선");

        expect(mockMemberService.findByMail(mail)).andReturn(member);
        replay(mockMemberService);
        request.addParameter("mail", mail);
        request.setMethod("POST");
        ModelAndView mav = controller.handleRequest(request, response);
        assertViewName(mav, "confirm");
        assertModelAttributeValue(mav, "member", member);
    }
}

EasyMock을 사용하여 MemberSerive의 Mock 객체를 사용했으며 spring-mock.jar의 MockHttpServletRequest와 MockHttpServletReponse를 사용했습니다.

여기서 주목할 것은 테스트의 대상인 ModelAndView 객체를 받아 올 때 호출한 메소드가 handleRequest라는 것입니다. 이 것은 Spring 의 Controller 클래스의 Workflow 때문이죠. 결국은 모든 컨트롤러들이 handleRequest로 요청을 처리하기 시작하기 때문입니다.