ServletUnit Cookbook


This is a brief document which shows you how to get started using ServletUnit(download)..

The Scenario : Lets say we have a servlet which generates some html output, upon the receipt of a http post. The post contains the name of a user. The servlet generates a response - Hello user (after you enter the name of the user in a html form and click submit).

Our Task : Check the output of doPost, when given a particular http request.

Our doPost method is coded like this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.io.*;
import javax.servlet.*;
import java.io.IOException;
import javax.servlet.http.*;

/**
 * This servlet displays Hello User in your browser
 * @author: Somik Raha
 */
public class HelloUser extends javax.servlet.http.HttpServlet 
{
        /**
         * HelloUser constructor comment.
         */
        public HelloUser() 
        {
                super();
        }
        /**
         * Insert the method´s description here.
         * Creation date: (5/6/2001 5:24:12 PM)
         */
         public void doPost(HttpServletRequest request,
                                          HttpServletResponse response)
                throws IOException, ServletException
         {
                response.setContentType("text/html");
                PrintWriter out = response.getWriter();
        
                String userName = request.getParameter("UserName");
                out.println("<html>");
                        out.println("<head>");
                                out.println("<title>Hello " +userName + "</title>");
                        out.println("</head>");

                        out.println("<body>");
                                out.println("<h1>Hello " + userName+ "!</h1>");
                        out.println("</body>");
                out.println("</html>");
         }
}

 

Our Process : We begin creating our testcase...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import com.kizna.servletunit.*;
import java.util.StringTokenizer;
import javax.servlet.ServletException;
import java.io.IOException;
import junit.framework.*;

/**
 * TestCase for HelloUser
 * @author: Somik Raha
 */
public class HelloUserTest extends junit.framework.TestCase 
{
        /**
         * HelloUserTest constructor comment.
         * @param name java.lang.String
         */
        public HelloUserTest(String name) 
        {
                super(name);
        }
        public static TestSuite suite()
        { 
                TestSuite suite = new TestSuite(HelloUserTest.class);
                return suite;
        }       
}

Run the test. It will fail saying that there are no tests to run.

Now, we start coding our test. This test is coded by looking at the code of doPost (not at the deployed output - avoid doing that, even if it might seem easier, for you will not be able to catch subtle errors which creep in due to your code).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public void testDoPost() 
{
        try
        {
                HttpServletRequestSimulator req = new HttpServletRequestSimulator();
                HttpServletResponseSimulator res = new HttpServletResponseSimulator();
                HelloUser servlet = new HelloUser();
                req.addParameter("UserName","John Doe");

                // Do the post
                servlet.doPost(req,res);
        
                // Test the output
                // Bring in the output
                String result=  res.getWriterBuffer().toString();

                // Instantiate the expected data
                  String expected =
                 "<html>\r\n"+
                         "<head>\r\n"+
                                 "<title>"+
                                         "Hello John Doe"+
                                 "</title>\r\n"+
                         "</head>\r\n"+
                         "<body>\r\n"+
                                 "<h1>Hello John Doe!</h1>\r\n"+
                         "</body>\r\n"+
                 "</html>\r\n";
                
                // Check if the result is the same as expected
                assertEquals("doPost result", expected,result);
        }
        catch (IOException e)
        {
                assert("IOException occurred while talking to servlet",false);
        }
        catch (ServletException e)
        {
                assert("ServletException occurred while talking to servlet",false);
        }
}

Run the test. It should run fine, and show you the green bar. But this test by itself is not going to help you much when there is a failure. Try it out, by introducing a space somewhere in the expected string, and watch the test fail. If it fails, it will be very hard for you to figure where the failure happened. (In fact, it is quite possible that if you try making this test on your own, you will end up with a failure due to some typographical error - dont worry, and proceed to the next step).

So, we shall modify the test a bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public void testDoPost() 
{
        try
        {
                HttpServletRequestSimulator req = new HttpServletRequestSimulator();
                HttpServletResponseSimulator res = new HttpServletResponseSimulator();
                HelloUser servlet = new HelloUser();
                req.addParameter("UserName","John Doe");

                // Do the post
                servlet.doPost(req,res);
        
                // Test the output
                // Bring in the output
                String result=  res.getWriterBuffer().toString();

                // Instantiate the expected data
                  String expected =
                 "<html>\r\n"+
                         "<head>\r\n"+
                                 "<title>"+
                                         "Hello John Doe"+
                                 "</title>\r\n"+
                         "</head>\r\n"+
                         "<body>\r\n"+
                                 "<h1>Hello John Doe!</h1>\r\n"+
                         "</body>\r\n"+
                 "</html>\r\n";
                
                // Check if the result is the same as expected
                StringTokenizer resultTok =new StringTokenizer(result,"\r\n");
                StringTokenizer expectedTok = new StringTokenizer(expected,"\r\n");
                while (resultTok.hasMoreTokens())
                {
                   assertEquals(expectedTok.nextToken(),resultTok.nextToken());
                }
        }
        catch (IOException e)
        {
                assert("IOException occurred while talking to servlet",false);
        }
        catch (ServletException e)
        {
                assert("ServletException occurred while talking to servlet",false);
        }
}

The part from line 26 to line 31 is the new addition. By tokenizing it based on each line, you will find it easier to zoom in on the line that caused the failure.
But sometimes, it would be hard to find the problem, by just looking at the line which caused the failure. e.g. delete line 21, compile and run the test case. You will see a failure like this :

junit.framework.AssertionFailedError: expected:<<h1>Hello John Doe!</h1>> but was:<<body>>

Unfortunately, for big and complex responses, we cannot easily figure out what happened, and it sometimes becomes necessary to also look at the whole output, to pinpoint the bug. So, you could modify line 28 to 31 to :

1
2
3
4
5
6
7
int line = 1;
while (resultTok.hasMoreTokens())
{
        assertEquals("Failure at line "+(line++)+",\n<EXPECTED OUPUT> : \n"+
        expected+"\n<ACTUAL OUTPUT> :\n"+result,
        expectedTok.nextToken(),resultTok.nextToken());
}

This will format your failure message in a more helpful way, and enable you to write a good testcase.

Once you are done with this testcase, and you get the green light, you are ready to deploy your servlet, and you know that its going to work.


For any comments or suggestions about the Cookbook or ServletUnit, please send your mails to :
Somik Raha
R&D Team
somik@kizna.com
http://www.kizna.com

Contributors :
Dane S. Foster
Equity Technology Group, Inc
http://www.equitytg.com
954.360.9800
dfoster@equitytg.com

Deryl Seale
deryl@acm.org

Neeraj Kumar
R&D Team
Eyesmax Software Corporation
New Delhi
91.11.551.5255
neeraj@eyesmaxsoftware.com
http://www.eyesmaxsoftware.com


This project is hosted at SourceForge
SourceForge Logo