The following is a simple example of a servlet we will write unit tests for:
The servlet:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Map;
public class MyServlet extends HttpServlet {
private MyService myService;
public void setMyService(MyService myService) {
this.myService = myService;
}
public void process(HttpServletRequest request, HttpServletResponse response) {
String action = request.getParameter("action");
if ("update".equals(action)) {
Map parameters = request.getParameterMap();
try {
myService.updateModel(parameters);
} catch (MyException e) {
request.setAttribute("error", e.getMessage());
}
}
request.setAttribute("model", myService.getModel());
getServletContext().getRequestDispatcher("myView.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}
}
The unit test:
* if the action is update, does it call myService.updateModel (example is below)
* if myService.updateModel throws an exception does the response contain the exceptions message (not implemented below)
import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
public class MyServletTest extends MockObjectTestCase {
private Mock mockMyService;
private Mock mockRequest;
private Mock mockResponse;
private MyService myService;
private HttpServletRequest request;
private HttpServletResponse response;
private MyServlet myServlet;
protected void setUp() throws java.lang.Exception {
mockMyService = mock(MyService.class);
mockRequest = mock(HttpServletRequest.class);
mockResponse = mock(HttpServletResponse.class);
myService = (MyService) mockMyService.proxy();
request = (HttpServletRequest) mockRequest.proxy();
response = (HttpServletResponse) mockResponse.proxy();
myServlet = new MyServlet();
}
public void testUpdate() {
// SETUP ANY OBJECTS USED ONLY IN THIS TESTCASE
Map parameters = new Hashtable();
// SETUP THE EXPECTED CALLS TO THE MOCK OBJECTS
// setup the mock request object to have the getParameter
// method called once with argument being equal to the
// string action and have it return the string update
mockRequest.expects(once()).method("getParameter").
with(eq("action")).will(returnValue("update"));
// setup the mock request object to have the getParameterMap
// method called once with no arguments and have it
// return an empty map
mockRequest.expects(once()).method("getParameterMap")
.will(returnValue(parameters));
// setup the mock myService object to have the updateModel
// method called once with the parameters map as the
// argument
mockMyService.expects(once()).method("updateModel").with(same(parameters));
// setup the mock myService object to have the getModel
// method called once with no arguments and have it
// return an empty map
mockMyService.expects(once()).method("getModel")
.will(returnValue(parameters));
// setup the mock myService object to have the updateModel
// method called once with the parameters map as the
// argument
mockRequest.expects(once()).method("setAttribute").with(eq("model"), same(parameters));
// RUN THE TEST
// add the myService mock object to the servlet so
// that it can handle calls later
myServlet.setMyService(myService);
myServlet.process(request, response);
}
}