Test a void method that redirect foward

旧城冷巷雨未停 提交于 2019-12-05 20:07:35

You need to create a mock of RequestDispatcher expecting to be forwarded, and return it from your mock:

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);

I will provide a long answer that should be helpful I think.

So, the tested method is this.

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){/* */}
}

A working test method would be this:

@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);
}

I am using mock() instead of createMock(). It's the same but nicer and shorter.

It returns a null dispatcher because nothing more is needed. I've added a verify() to make sure everything was called as expected.

Then, if you want to make sure the forward is called as well, you also need a mock for the 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);
}

The verify() will make sure forward() is called. You do not need an expectLastCall(). It is implicit.

Then to simplify, I would actually do this:

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();
    }
}

The EasyMockSupport class makes the code simpler.

And to be honest, in this case, when using Spring, I would use 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");
}

It does the exact same thing but as you can see it is much shorter because the session and request dispatcher are created under the hood to behave like you would expect.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!