Я предоставлю длинный ответ, который должен быть полезным, я думаю.
Итак, проверенный метод таков.
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");
}
Он делает то же самое, но, как вы можете видеть, он намного короче, потому что диспетчер сеансов и запросов создается под капотом, чтобы вести себя так, как вы ожидаете.