Reputation: 79635
I have a servlet called Calculator
. It reads the parameters left
, right
and op
and returns by setting an attribute result
in the response.
What is the easiest way to unit test this: basically I want to create an HttpServletRequest, set the parameters, and then checking the response - but how do I do that?
Here's the servlet code (it's small and silly on purpose):
public class Calculator extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
public Calculator() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Integer left = Integer.valueOf(request.getParameter("left"));
Integer right = Integer.valueOf(request.getParameter("right"));
Integer result = 0;
String op = request.getParameter("operator");
if ("add".equals(op)) result = this.opAdd(left, right);
if ("subtract".equals(op)) result = this.opSub(left, right);
if ("multiply".equals(op)) result = this.opMul(left, right);
if ("power".equals(op)) result = this.opPow(left, right);
if ("divide".equals(op)) result = this.opDiv(left, right);
if ("modulo".equals(op)) result = this.opMod(left, right);
request.setAttribute("result", result); // It'll be available as ${sum}.
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
...
}
Upvotes: 4
Views: 16362
Reputation: 1219
Can't say this is the best method to do so : but to unit test a simple servlet like that (one not using forwards, context etc..) what you could simply do is :
op=add
for a addition unit test. If you are using custom classes, you can simply set them in an internal properties object. If you are using mocks, then settings expectations would do.new Calculator()
, keeping the required libs in the class path. Now call the service
method on this instance.For mocking, a simply starting point would be EasyMock or Mockito (my fav)
An example for the wrapper : http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletRequestWrapper.html
HTH
Upvotes: 1
Reputation: 31795
Generally you should abstract your business logic from Servlet container details. You can mock ServletRequest using Spring test package, but it would be a bad idea to simulate Servlet container. So, you should either run system tests on a real container or move your logic from servlet into a separate bean and test it in isolation.
public class Calculator {
public Integer calculate(Integer left, Integer right, String op) {
Integer result = 0;
if ("add".equals(op)) result = this.opAdd(left, right);
if ("subtract".equals(op)) result = this.opSub(left, right);
if ("multiply".equals(op)) result = this.opMul(left, right);
if ("power".equals(op)) result = this.opPow(left, right);
if ("divide".equals(op)) result = this.opDiv(left, right);
if ("modulo".equals(op)) result = this.opMod(left, right);
return result;
}
}
public class CalculatorServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Integer left = Integer.valueOf(request.getParameter("left"));
Integer right = Integer.valueOf(request.getParameter("right"));
String op = request.getParameter("operator");
Integer result = calculator.calculate(left, right, op);
request.setAttribute("result", result); // It'll be available as ${sum}.
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
Upvotes: 0
Reputation: 269667
Often, the important logic of a program is factored out into other classes, that are usable in a variety of contexts, instead of being tightly coupled to a Servlet Engine. This leaves the servlet itself as a simple adapter between the web and your application.
This makes the program easier to test, and easier to reuse in other contexts like a desktop or mobile app.
Upvotes: 12
Reputation: 193
There are a few libraries out there that you can use. Are you using Spring http://www.springsource.org/ in your application? If so, there is one application for spring (spring-test) that contains MockHttpServletRequest. For example:
@Test
public void shouldReturnAValidaRedirectionMessage() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("op", "addition");
request.addParameter("left", "1");
request.addParameter("right", "5");
CalculatorServlet servlet = new CalculatorServlet();
Operation operation = servlet.getOperation(request);
assertNotNull(operation);
assertEquals(ADDITION, operation.getOperationType());
...
Upvotes: 10
Reputation: 3508
Check out ServletUnit. It's part of HttpUnit.
http://httpunit.sourceforge.net/doc/servletunit-intro.html
Upvotes: 1