测试重定向foward的void方法

时间:2018-04-30 18:39:51

标签: java unit-testing junit easymock

如何测试使用RequestDispatcher重定向我的void方法?

到目前为止我做了什么。

public void testAuthAction_userNull() {
    HttpServletRequest requestMock = createMock(HttpServletRequest.class);
    HttpServletResponse responseMock = createMock(HttpServletResponse.class);
    expect(requestMock.getSession().getAttribute("user")).andReturn(null);
    replay(requestMock);

    AuthAction action = new AuthAction();
    RequestDispatcher rd = requestMock.getRequestDispatcher("/User/login.jsp");
}

我想要测试的方法是。

public void execute(HttpServletRequest request, HttpServletResponse response) {
    User user = (User) request.getSession().getAttribute("User");
    try {
        if(user == null) {
            RequestDispatcher rd = request.getRequestDispatcher("/User/login.jsp");
            if(rd != null)
                rd.foward(request, response);
        } else {/* */}
    }
    catch(Exception e){/* */}
}

我正在使用JUnit和EasyMock。

2 个答案:

答案 0 :(得分:1)

您需要创建一个期望转发的RequestDispatcher模拟,然后从模拟中返回:

RequestDispatcher dispatcherMock = createMock(RequestDispatcher.class);
expect(requestMock.getRequestDispatcher("/User/login.jsp"))
    .andReturn(dispatcherMock);
// Expect to be forwarded.
dispatcherMock.forward(requestMock, responseMock);
EasyMock.expectLastCall().once();
replay(dispatcherMock);
replay(requestMock);

// Run your test on whatever instance has `execute`:
someInstance.execute(requestMock, responseMock);

答案 1 :(得分:0)

我会提供一个应该有用的长答案。

所以,测试方法就是这样。

public void execute(HttpServletRequest request, HttpServletResponse response) {
    User user = (User) request.getSession().getAttribute("User");
    try {
        if(user == null) {
            RequestDispatcher rd = request.getRequestDispatcher("/User/login.jsp");
            if(rd != null)
                rd.forward(request, response);
        } else {/* */}
    }
    catch(Exception e){/* */}
}

工作测试方法是:

@Test
public void testAuthAction_userNull() {
    HttpServletRequest requestMock = mock(HttpServletRequest.class);
    HttpServletResponse responseMock = mock(HttpServletResponse.class);
    HttpSession sessionMock = mock(HttpSession.class);

    expect(requestMock.getSession()).andReturn(sessionMock);
    expect(sessionMock.getAttribute("User")).andReturn(null);
    expect(requestMock.getRequestDispatcher("/User/login.jsp")).andReturn(null);

    replay(requestMock, sessionMock);

    execute(requestMock, responseMock);

    verify(requestMock, sessionMock);
}

我使用mock()代替createMock()。它是相同的但更好更短。

它返回一个空调度程序,因为不再需要它。我添加了verify()以确保按预期调用所有内容。

然后,如果你想确保调用前锋,你还需要模拟RequestDispatcher

@Test
public void testAuthAction_userNull() throws Exception {
    HttpServletRequest requestMock = mock(HttpServletRequest.class);
    HttpServletResponse responseMock = mock(HttpServletResponse.class);
    HttpSession sessionMock = mock(HttpSession.class);
    RequestDispatcher rdMock = mock(RequestDispatcher.class);

    expect(requestMock.getSession()).andReturn(sessionMock);
    expect(sessionMock.getAttribute("User")).andReturn(null);
    expect(requestMock.getRequestDispatcher("/User/login.jsp")).andReturn(rdMock);

    rdMock.forward(requestMock, responseMock);

    replay(requestMock, sessionMock, rdMock);

    execute(requestMock, responseMock);

    verify(requestMock, sessionMock, rdMock);
}

verify()将确保调用forward()。您不需要expectLastCall()。这是隐含的。

然后为了简化,我实际上会这样做:

public class MyTest extends EasyMockSupport {
    @Test
    public void testAuthAction_userNull() throws Exception {
        HttpServletRequest requestMock = mock(HttpServletRequest.class);
        HttpServletResponse responseMock = mock(HttpServletResponse.class);
        HttpSession sessionMock = mock(HttpSession.class);
        RequestDispatcher rdMock = mock(RequestDispatcher.class);

        expect(requestMock.getSession()).andReturn(sessionMock);
        expect(sessionMock.getAttribute("User")).andReturn(null);
        expect(requestMock.getRequestDispatcher("/User/login.jsp")).andReturn(rdMock);

        rdMock.forward(requestMock, responseMock);

        replayAll();

        execute(requestMock, responseMock);

        verifyAll();
    }
}

EasyMockSupport类使代码更简单。

说实话,在这种情况下,使用Spring时,我会使用spring-test

@Test
public void testAuthAction_userNull() throws Exception {
    MockHttpServletRequest request = new MockHttpServletRequest();
    MockHttpServletResponse response = new MockHttpServletResponse();

    execute(request, response);

    assertThat(response.getForwardedUrl()).isEqualTo("/User/login.jsp");
}

它做的完全相同,但你可以看到它更短,因为会话和请求调度程序是在底层创建的,表现得像你期望的那样。