junit как протестировать Filter?
Есть фильтр который добавляет хедер ко всем запросам
@Component("xForwardedForAppenderFilter")
public class XForwardedForAppenderFilter extends OncePerRequestFilter {
private static final String CLIENT_IP_HEADER = "X-Forwarded-For";
private static final String FAKE_CLIENT_IP = "11.22.33.44";
@Override
protected void doFilterInternal(@NonNull HttpServletRequest httpServletRequest, @NonNull HttpServletResponse httpServletResponse,
@NonNull FilterChain filterChain) throws ServletException, IOException
{
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpServletRequest) {
@Override
public String getHeader(String name) {
if (CLIENT_IP_HEADER.equals(name) && StringUtils.isBlank(super.getHeader(name)))
return FAKE_CLIENT_IP;
return super.getHeader(name);
}
@Override
public Enumeration<String> getHeaders(String name) {
if (CLIENT_IP_HEADER.equals(name) && !super.getHeaders(name).hasMoreElements())
return Collections.enumeration(Collections.singleton(FAKE_CLIENT_IP));
return super.getHeaders(name);
}
};
filterChain.doFilter(requestWrapper, httpServletResponse);
}
Написал следующий тест, но при вызове getHeader фильтр не срабатывает.
@RunWith(MockitoJUnitRunner.class)
public class XForwardedForAppenderFilterTest {
private static final String CLIENT_IP_HEADER = "X-Forwarded-For";
private static final String FAKE_CLIENT_IP = "11.22.33.44";
@InjectMocks
private XForwardedForAppenderFilter xForwardedForAppenderFilter;
@Test
public void doFilterInternal() throws ServletException, IOException {
MockHttpServletRequest httpServletRequest = new MockHttpServletRequest();
MockHttpServletResponse httpServletResponse = new MockHttpServletResponse();
httpServletRequest.addHeader("test","12345");
MockFilterChain filterChain = new MockFilterChain();
xForwardedForAppenderFilter.doFilterInternal(httpServletRequest, httpServletResponse, filterChain);
Assert.assertTrue(httpServletRequest.getHeader(CLIENT_IP_HEADER).equals(FAKE_CLIENT_IP));
Assert.assertTrue(httpServletRequest.getHeaders(CLIENT_IP_HEADER).nextElement().equals(FAKE_CLIENT_IP));
}
}
Как заставить фильтр запускаться в тесте?
Ответы (1 шт):
Вы проверяете не тот объект request.
Фильтр у вас берет входящий request, заворачивает его в обертку, в которой дополнительный функционал, и вызывает следующий фильтр в цепочке уже с оберткой.
Так вот, вы в тесте проверяете входящий request (он у вас хранится в httpServletRequest), а нужно проверять, тот, который передается по цепочке дальше. Для этого у вас есть MockFilterChain, который как раз и нужен, чтоб сохранить этот новый request, чтоб его можно было проверить:
MockFilterChain filterChain = new MockFilterChain();
xForwardedForAppenderFilter.doFilterInternal(
httpServletRequest, httpServletResponse, filterChain);
ServletRequest request = filterChain.getRequest();
Assert.assertTrue(request.getHeader(CLIENT_IP_HEADER).equals(FAKE_CLIENT_IP));
Assert.assertTrue(request.getHeaders(CLIENT_IP_HEADER).nextElement().equals(FAKE_CLIENT_IP));
И еще, не используйте assertTrue для проверки равенства. При неравенстве, ошибка не покажет значений. Используйте assertEquals:
Assert.assertEquals(request.getHeader(CLIENT_IP_HEADER), FAKE_CLIENT_IP);