java 如何对 servlet 进行单元测试?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4137484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:57:43  来源:igfitidea点击:

How do I Unit Test a servlet?

javaunit-testingjspservletsjunit

提问by Amir Rachum

I have a servlet called Calculator. It reads the parameters left, rightand opand returns by setting an attribute resultin the response.

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

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?

对此进行单元测试的最简单方法是什么:基本上我想创建一个 HttpServletRequest,设置参数,然后检查响应 - 但我该怎么做呢?

Here's the servlet code (it's small and silly on purpose):

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

}

}

回答by erickson

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.

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

This makes the program easier to test, and easier to reuse in other contexts like a desktop or mobile app.

这使程序更易于测试,并且更易于在桌面或移动应用程序等其他上下文中重用。

回答by marcelo

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:

您可以使用一些库。您是否在应用程序中使用 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());
            ...

回答by Todd

Check out ServletUnit. It's part of HttpUnit.

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

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

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

回答by madhurtanwani

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 :

不能说这是最好的方法:但是要对这样的简单 servlet(不使用转发、上下文等)进行单元测试,您可以简单地做的是:

  1. Create mock HttpServletReqeust and HttpServletResponse instances using any mocking library. Even simpler would be using RequestWrapper and ResponseWrapper classes (simple custom classes implemented by extending the HttpServletReqeust and HttpServletResponse classes).
  2. On these mock (or custom) instances set certain properties - the parameters you want to test against in each test case - e.g. op=addfor 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.
  3. Create an instance of the servlet - new Calculator(), keeping the required libs in the class path. Now call the servicemethod on this instance.
  4. When the call returns, get the o/p from the response class and assert it. Since the response class is again a custom class or a mocked version, this should be easy.
  1. 使用任何模拟库创建模拟 HttpServletReqeust 和 HttpServletResponse 实例。更简单的是使用 RequestWrapper 和 ResponseWrapper 类(通过扩展 HttpServletReqeust 和 HttpServletResponse 类实现的简单自定义类)。
  2. 在这些模拟(或自定义)实例上设置某些属性 - 您要在每个测试用例中测试的参数 - 例如,op=add用于附加单元测试。如果您使用自定义类,您可以简单地在内部属性对象中设置它们。如果您正在使用模拟,那么设置期望就可以了。
  3. 创建 servlet - 的实例,new Calculator()在类路径中保留所需的库。现在调用service此实例上的方法。
  4. 当调用返回时,从响应类中获取 o/p 并对其进行断言。由于响应类再次是自定义类或模拟版本,这应该很容易。

For mocking, a simply starting point would be EasyMock or Mockito (my fav)

对于模拟,一个简单的起点是 EasyMock 或 Mockito(我的最爱)

An example for the wrapper : http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletRequestWrapper.html

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

HTH

HTH

回答by Eugene Kuleshov

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.

通常,您应该从 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);
   }
 }