Writing Unit Tests For Servlet Filters using Spring’s Mock Classes
Unit testing is a lot easier if you don’t have to run a web container, and the spring framework includes a library of solid mock classes for testing. There are a ton of pages out there talking about how to test Spring MVC controllers with the mock classes so I’m not going to get into that. I will instead walk through testing a Servlet Filter.
The filter is a pretty lame filter called StrangeFilter. All is does is forward requests with a parameter set.
package com.nthread.sandbox;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class StrangeFilter implements Filter {
private FilterConfig filterConfig;
public StrangeFilter() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
if ("okay".equals(request.getParameter(""))) {
this.filterConfig.getServletContext()
.getRequestDispatcher("/fail.html")
.forward(request, response);
} else {
chain.doFilter(request, response);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
// TODO Auto-generated method stub
}
}
To test this filter without a web container is really pretty easy. You need to make use of four Mock classes provided by the Spring test framework, but basically, it’s just as easy as any other unit test. I think the code pretty much speaks for itself, so here it is.
package com.nthread.sandbox;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.io.IOException;
import javax.servlet.ServletException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
public class StrangeFilterTest {
private StrangeFilter filter;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private MockFilterChain chain;
@Before
public void setUp() throws Exception {
filter = new StrangeFilter();
filter.init(new MockFilterConfig());
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
chain = new MockFilterChain();
}
@Test
public void testDoFilterWithFail() throws IOException, ServletException {
request.addParameter("failThis", "okay");
filter.doFilter(request, response, chain);
assertEquals("/fail.html", response.getForwardedUrl());
}
@Test
public void testDoFilterWithoutFail() throws IOException, ServletException {
filter.doFilter(request, response, chain);
assertNull(response.getForwardedUrl());
}
}
