Servlet mocking with Mockito

When writing custom servlets, it can be quite useful to unit test them.  In my case, I used a combination of testng and mockito.  The basic idea is simple; mock a HttpServletRequest, and a HttpServletResponse and pass them to the custom servlet.  There is a bit more too it, so here's an example.

final HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
when(httpServletRequest.getPathInfo()).thenReturn("/lineup/world.xml");
final HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
final StubServletOutputStream servletOutputStream = new StubServletOutputStream();
when(httpServletResponse.getOutputStream()).thenReturn(servletOutputStream);
final ServletConfig servletConfig = mock(ServletConfig.class);
when(servletConfig.getInitParameter("defaultPool")).thenReturn("testpool1");

This sets up an HttpServletRequest, an HttpServletResponse, a ServletConfig where i can pass in parameters that the container would have read from web.xml, and a "StubServletOutputStream", which is just a convenient wrapper around a ByteArrayOutputStream.

My StubServletOutputStream looks like this:

public class StubServletOutputStream extends ServletOutputStream {
 public ByteArrayOutputStream baos = new ByteArrayOutputStream();
   public void write(int i) throws IOException {
    baos.write(i);
 }
}

It's necessary to init() the servlet, something the container would normally do:

final MyServlet myServlet = new MyServlet();
myServlet.init(servletConfig);

Finally; I invoke my servlet, and check the output:

restCacheServlet.doGet(httpServletRequest, httpServletResponse);
final byte[] data = servletOutputStream.baos.toByteArray();
Assert.assertNotNull(data);
Assert.assertTrue(data.length > 0);

8 Responses to "Servlet mocking with Mockito"

  • Tomek
    August 21, 2013 - 2:58 am Reply

    hi, nice trick! I have introduced a minor change so the class looks like this:

    public class FakeServletOutputStream extends ServletOutputStream {
    private ByteArrayOutputStream baos = new ByteArrayOutputStream();
    public void write(int i) throws IOException {
    baos.write(i);
    }

    public String getContent() {
    return baos.toString();
    }
    }

    • tom@khubla.com
      August 24, 2013 - 6:59 pm Reply

      Nice work! Thanks!

  • Albert
    November 24, 2013 - 11:07 am Reply

    Than you Tomek! It worked!

  • Lord-Pinhead
    February 18, 2014 - 11:51 am Reply

    Is there a way to setup the context too? In my app, i use the context to store Database things like status of something , so i dont have to query the db everytime i open my formulars, they change never and now i want to test an method like getIdFromRequest or getStatusFromContext. Productioncode works but i have to refactor it and i have no tests, just a few integration tests. Maybe there is a tweak to init the context inside my servlet .

    greetings Lordi

  • Elan
    June 9, 2014 - 2:17 pm Reply

    Thanks. It worked and helped me :).

  • Navneet
    May 31, 2017 - 8:08 am Reply

    Thanks Man. It worked for me.
    This code is pure gold. I was struck for 3hrs on mocking invoking the servlet, and finally it worked.

    Thanks a lot

    • tom@khubla.com
      July 23, 2017 - 1:51 pm Reply

      You’re quite welcome.

Leave a Reply