Как сделать unit test сервлет-фильтр с помощью jUnit?
Реализовано doFilter()
. Как правильно накрыть фильтр с помощью jUnit?
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws java.io.IOException, javax.servlet.ServletException
{
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String currentURL = request.getRequestURI();
if (!currentURL.equals("/maintenance.jsp") && modeService.getOnline())
{
response.sendRedirect("/maintenance.jsp");
}
filterChain.doFilter(servletRequest, servletResponse);
}
Ответы
Ответ 1
ServletRequest
, ServletResponse
и FilterChain
- все интерфейсы, поэтому вы можете легко создавать тестовые заглушки для них либо вручную, либо используя насмешливую структуру.
Сделайте объекты макета конфигурируемыми, чтобы подготовить готовый ответ к getRequestURI()
и чтобы вы могли запросить ServletResponse, чтобы утверждать, что sendRedirect был вызван.
Ввести макет ModeService.
Вызвать doFilter, передавая макету ServletRequest, ServletResponse и FilterChain в качестве параметров.
@Test
public void testSomethingAboutDoFilter() {
MyFilter filterUnderTest = new MyFilter();
filterUnderTest.setModeService(new MockModeService(ModeService.ONLINE));
MockFilterChain mockChain = new MockFilterChain();
MockServletRequest req = new MockServletRequest("/maintenance.jsp");
MockServletResponse rsp = new MockServletResponse();
filterUnderTest.doFilter(req, rsp, mockChain);
assertEquals("/maintenance.jsp",rsp.getLastRedirect());
}
На практике вам нужно переместить установку в метод @Before setUp()
и написать больше методов @Test, чтобы охватить все возможные пути выполнения.
... и вы, вероятно, будете использовать насмешливую структуру, такую как JMock или Mockito, чтобы создавать макеты, а не гипотетические MockModeService
и т.д. Я использовал здесь.
Это метод модульного тестирования, а не интеграционный тест. Вы выполняете только тестируемое устройство (и тестовый код).
Ответ 2
Вы можете использовать фальшивую фреймворк, чтобы издеваться над объектами HttpServletRequest
, HttpServletResponse
и FilterChain
и их поведением. В зависимости от структуры у вас есть определенная функциональность, чтобы проверить, выполняются ли во время выполнения кода правильные действия над издеваемыми объектами.
Например, при использовании фреймворка Mockito, предоставленный метод doFilter()
может быть проверен JUnit с использованием ниже тестового примера:
@Test
public void testDoFilter() throws IOException, ServletException {
// create the objects to be mocked
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
FilterChain filterChain = mock(FilterChain.class);
// mock the getRequestURI() response
when(httpServletRequest.getRequestURI()).thenReturn("/otherurl.jsp");
MaintenanceFilter maintenanceFilter = new MaintenanceFilter();
maintenanceFilter.doFilter(httpServletRequest, httpServletResponse,
filterChain);
// verify if a sendRedirect() was performed with the expected value
verify(httpServletResponse).sendRedirect("/maintenance.jsp");
}
Ответ 3
Если вы используете Spring, то у него есть собственные mocks:
- org.springframework.mock.web.MockFilterChain
- org.springframework.mock.web.MockHttpServletRequest
- org.springframework.mock.web.MockHttpServletResponse
Например, вы можете добавить заголовки и установить тест Uri.
Итак, ваш тест может быть таким:
@RunWith(MockitoJUnitRunner.class)
public class TokenAuthenticationFilterTest {
private static final String token = "260bce87-6be9-4897-add7-b3b675952538";
private static final String testUri = "/testUri";
@Mock
private SecurityService securityService;
@InjectMocks
private TokenAuthenticationFilter tokenAuthenticationFilter = new TokenAuthenticationFilter();
@Test
public void testDoFilterInternalPositiveScenarioWhenTokenIsInHeader() throws ServletException, IOException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader(TOKEN, token);
request.setRequestURI(testUri);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain filterChain = new MockFilterChain();
when(securityService.doesExistToken(token)).thenReturn(true);
tokenAuthenticationFilter.doFilterInternal(request, response, filterChain);
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
}
}