This page demonstrates the testing of servlets and filters. The release comes with more detailed examples.
This servlet creates a redirect HTML page. The redirect URL can be specified with the request parameter redirecturl.
public class RedirectServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String redirectUrl = request.getParameter("redirecturl"); StringBuffer output = new StringBuffer(); output.append("<html>\n"); output.append("<head>\n"); output.append("<meta http-equiv=\"refresh\" content=\""); output.append("0;URL=" + redirectUrl + "\">\n"); output.append("</head>\n"); output.append("<body>\n"); output.append("<h3>"); output.append("You will be redirected to "); output.append("<a href=\"" + redirectUrl + "\">"); output.append(redirectUrl + "</a>"); output.append("</h3>\n"); output.append("</body>\n"); output.append("</html>\n"); response.getWriter().write(output.toString()); } }
Now we want to write a test if the servlet creates the correct HTML code. First we simply go through the output text line by line.
public class RedirectServletTest extends BasicServletTestCaseAdapter { protected void setUp() throws Exception { super.setUp(); createServlet(RedirectServlet.class); } public void testServletOutput() throws Exception { addRequestParameter("redirecturl", "http://www.mockrunner.com"); doPost(); BufferedReader reader = getOutputAsBufferedReader(); assertEquals("<html>", reader.readLine().trim()); assertEquals("<head>", reader.readLine().trim()); reader.readLine(); assertEquals("</head>", reader.readLine().trim()); assertEquals("<body>", reader.readLine().trim()); reader.readLine(); assertEquals("</body>", reader.readLine().trim()); assertEquals("</html>", reader.readLine().trim()); verifyOutputContains("URL=http://www.mockrunner.com"); } }
We only test the overall HTML structure and the redirect URL. The framework provides the generated HTML output in different formats, e.g. as String, as Reader or as parsed XML. The HTML does not necessarily have to be wellformed XML. Mockrunner is using NekoHTML for parsing the HTML output. In the following test method, we test the content of the HTML using JDOM.
public class RedirectServletTest extends BasicServletTestCaseAdapter { protected void setUp() throws Exception { super.setUp(); createServlet(RedirectServlet.class); } public void testServletOutputAsXML() throws Exception { addRequestParameter("redirecturl", "http://www.mockrunner.com"); doPost(); Element root = getOutputAsJDOMDocument().getRootElement(); assertEquals("html", root.getName()); Element head = root.getChild("head"); Element meta = head.getChild("meta"); assertEquals("refresh", meta.getAttributeValue("http-equiv")); assertEquals("0;URL=http://www.mockrunner.com", meta.getAttributeValue("content")); } }
In the next example we'll test a servlet, that invalidates the session and redirects to a goodbye page when the user clicks the logout button.
public class LogoutServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String logout = request.getParameter("logout"); if(null != logout) { request.getSession().invalidate(); RequestDispatcher dispatcher = request.getRequestDispatcher("/html/goodbye.html"); dispatcher.forward(request, response); } } }
If you use <input type="image"/> instead of <input type="submit"/> on the HTML page for the logout button, you get logout.x and logout.y as request parameters. We can use a filter in front of the servlet. This filter changes the request parameters so the servlet only gets one logout parameter. The following code fragment only shows the Filter, please check out the release for the complete source code of ImageButtonRequestWrapper.
public class ImageButtonFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if(request instanceof HttpServletRequest) { ImageButtonRequestWrapper wrapper = new ImageButtonRequestWrapper((HttpServletRequest)request); chain.doFilter(wrapper, response); } else { chain.doFilter(request, response); } } public void init(FilterConfig filterConfig) {} public void destroy() {} }
Now we want to write a test for the LogoutServlet with the ImageButtonFilter and a simulated image button.
public class LogoutServletTest extends BasicServletTestCaseAdapter { public void testDoLogoutWithFilteredImageButton() throws Exception { addRequestParameter("logout.x", "11"); addRequestParameter("logout.y", "12"); createFilter(ImageButtonFilter.class); createServlet(LogoutServlet.class); setDoChain(true); doPost(); assertFalse(getWebMockObjectFactory().getMockSession().isValid()); HttpServletRequest filteredRequest = (HttpServletRequest)getFilteredRequest(); assertEquals("11", filteredRequest.getParameter("logout")); assertNull(filteredRequest.getParameter("logout.x")); assertNull(filteredRequest.getParameter("logout.y")); } }
It's really easy. We simply create the filter and the servlet and call the doPost() method. The framework processes the filter chain as in the real webcontainer.
You can extend your test from BasicServletTestCaseAdapter or ServletTestCaseAdapter or delegate to ServletTestModule, like with the other test modules of Mockrunner.