我如何对servlet进行unit testing?

我有一个名为Calculator的servlet。 它通过在响应中设置属性result来读取leftrightop的参数并返回。

unit testing的最简单方法是什么:基本上我想创建一个HttpServletRequest,设置参数,然后检查响应 – 但我该怎么做?

这是servlet代码(它的目的很小而且很愚蠢):

 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); } } ... 

}

通常,程序的重要逻辑被分解为可在各种上下文中使用的其他类,而不是紧密耦合到Servlet引擎。 这使servlet本身成为Web和应用程序之间的简单适配器。

这使程序更容易测试,并且更容易在桌面或移动应用程序等其他环境中重用。

你可以使用一些库。 您在应用程序中使用Spring http://www.springsource.org/吗? 如果是这样,有一个包含MockHttpServletRequest的spring(spring-test)应用程序。 例如:

 @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()); ... 

查看ServletUnit。 它是HttpUnit的一部分。

http://httpunit.sourceforge.net/doc/servletunit-intro.html

不能说这是最好的方法:但要unit testing这样一个简单的servlet(一个不使用转发,上下文等……)你可以简单地做的是:

  1. 使用任何模拟库创建模拟HttpServletReqeust和HttpServletResponse实例。 更简单的是使用RequestWrapper和ResponseWrapper类(通过扩展HttpServletReqeust和HttpServletResponse类实现的简单自定义类)。
  2. 在这些模拟(或自定义)实例上设置某些属性 – 在每个测试用例中要测试的参数 – 例如op=add用于加法unit testing。 如果您使用自定义类,则只需在内部属性对象中设置它们即可。 如果您正在使用模拟,那么设置期望就可以了。
  3. 创建servlet的实例 – new Calculator() ,将所需的lib保留在类路径中。 现在调用此实例上的service方法。
  4. 当调用返回时,从响应类中获取o / p并断言它。 由于响应类同样是自定义类或模拟版本,因此这应该很容易。

对于嘲弄,一个简单的起点是EasyMock或Mockito(我的collections)

包装器的一个示例: http : //tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletRequestWrapper.html

HTH

通常,您应该从Servlet容器详细信息中抽象出业务逻辑。 你可以使用Spring测试包来模拟ServletRequest,但是模拟Servlet容器是个坏主意。 因此,您应该在真实容器上运行系统测试,或者将您的逻辑从servlet移动到单独的bean中并单独测试它。

  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); } }