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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14404808/
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-31 16:10:15  来源:igfitidea点击:

How do I Unit Test HTTPServlet?

javaunit-testingjunitmocking

提问by Matti Kiviharju

I want to test my servlet with http://www.easymock.org/

我想用http://www.easymock.org/测试我的 servlet

How do I write the Unit Testing Code?

如何编写单元测试代码?

I update my code with your responce.

我根据您的回复更新了我的代码。

I just used Google and made this code now.

我刚刚使用谷歌并制作了这段代码。

Here is my Servlet:

这是我的 Servlet:

 package com.i4ware.plugin.timesheet;

 import java.io.IOException;

 import com.atlassian.jira.issue.Issue;
 import com.atlassian.jira.issue.IssueManager;
 import com.atlassian.jira.project.Project;
 import com.atlassian.jira.project.ProjectManager;
 import org.ofbiz.core.entity.DelegatorInterface;
 import org.ofbiz.core.entity.EntityExpr;
 import org.ofbiz.core.entity.EntityOperator;
 import org.ofbiz.core.entity.GenericEntityException;
 import org.ofbiz.core.entity.GenericValue;
 import org.ofbiz.core.util.UtilMisc;
 import org.apache.commons.lang.StringEscapeUtils;
 import com.atlassian.crowd.embedded.api.User;
 import com.atlassian.jira.security.JiraAuthenticationContext;
 import com.atlassian.jira.web.bean.PagerFilter;
 import com.atlassian.jira.issue.search.SearchResults;
 import com.atlassian.jira.bc.issue.search.SearchService;
 import com.atlassian.jira.issue.search.SearchException;

 import com.atlassian.jira.issue.worklog.Worklog;
 import com.atlassian.jira.issue.worklog.WorklogManager;
 import com.atlassian.jira.issue.worklog.WorklogImpl;

 import com.atlassian.query.Query;
 import com.atlassian.jira.jql.builder.JqlQueryBuilder;
 import com.atlassian.query.order.SortOrder;

 import com.atlassian.jira.issue.status.Status; 

 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 import com.atlassian.jira.util.json.JSONObject;
 import com.atlassian.jira.util.json.JSONException;
 import com.atlassian.jira.util.json.JSONArray;

 import java.io.UnsupportedEncodingException;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Collections;
import java.lang.Long;
import java.util.Collection;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.lang.Class;
import java.util.Enumeration;

import org.apache.log4j.Category;

import com.atlassian.upm.api.license.entity.PluginLicense;
import com.atlassian.upm.license.storage.lib.PluginLicenseStoragePluginUnresolvedException;
import com.atlassian.upm.license.storage.lib.ThirdPartyPluginLicenseStorageManager;

import com.atlassian.plugin.webresource.WebResourceManager;
 import com.atlassian.templaterenderer.TemplateRenderer;

import java.text.ParseException;
import java.text.ParsePosition;

 public class UserIsLogedInServlet extends HttpServlet
 {
private static final Category log = Category.getInstance(UserIsLogedInServlet.class);
/** value is made for JSON {"success":true} or {"success":false}. */
private Boolean value;    

private String json;
private String msg;
private final ThirdPartyPluginLicenseStorageManager licenseManager;
private WebResourceManager webResourceManager;
private final TemplateRenderer renderer;

private JiraAuthenticationContext authenticationContext;    

public UserIsLogedInServlet(ThirdPartyPluginLicenseStorageManager licenseManager,
        WebResourceManager webResourceManager,
        TemplateRenderer renderer,
        JiraAuthenticationContext authenticationContext)
{
    this.licenseManager = licenseManager;
    this.webResourceManager = webResourceManager;
    this.renderer = renderer;
    this.authenticationContext = authenticationContext;
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
    resp.setContentType("application/json");        

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{       

    User targetUser = authenticationContext.getLoggedInUser();

    String user = "";

    if (targetUser==null) {

        user = "anonymous";
        value = Boolean.valueOf(!"false"
            .equalsIgnoreCase((String) "false"));
        msg = "You're not loged in.";
    } else {

        user = targetUser.getName();
        value = Boolean.valueOf(!"false"
            .equalsIgnoreCase((String) "true"));
        msg = "You're loged in.";
    }        

    try {

    json = new JSONObject()      
    .put("msg", msg)
    .put("success", value)
    .toString();

    } catch (JSONException err) {
        err.printStackTrace();
        System.out.println("Got an JSONException: " + err.getCause());
    }

    resp.setContentType("application/json");        
    resp.getWriter().write(json);
    resp.getWriter().close();

}
}

Here is code:

这是代码:

package com.i4ware.plugin.timesheet;

import junit.framework.*;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.BeforeClass;
import org.junit.After;
import java.io.*;
import java.security.*;
import javax.servlet.http.*;
import javax.servlet.ServletException;
import javax.servlet.RequestDispatcher;
import static org.easymock.EasyMock.*;
import org.easymock.IMocksControl;
import com.atlassian.upm.api.license.entity.PluginLicense;
import com.atlassian.upm.license.storage.lib.PluginLicenseStoragePluginUnresolvedException;
import com.atlassian.upm.license.storage.lib.ThirdPartyPluginLicenseStorageManager;
import com.atlassian.plugin.webresource.WebResourceManager;
import com.atlassian.templaterenderer.TemplateRenderer;
import com.atlassian.jira.security.JiraAuthenticationContext;

import com.i4ware.plugin.timesheet.UserIsLogedInServlet;

public class UserIsLogedInServletTest extends TestCase {    

private ThirdPartyPluginLicenseStorageManager licenseManager;
private WebResourceManager webResourceManager;
private TemplateRenderer renderer;  
private JiraAuthenticationContext authenticationContext;

private IMocksControl mocks;
private UserIsLogedInServlet servlet;

@BeforeClass
public void setUpBeforeClass() {
    mocks = (IMocksControl) createStrictControl();
    servlet = new UserIsLogedInServlet(licenseManager,webResourceManager,renderer,authenticationContext);
}

@After
public void tearDown() {
    mocks.reset();
}

@Test
public void testGet()throws ServletException, IOException {
    HttpServletRequest request = mocks.createMock(HttpServletRequest.class);
    HttpServletResponse response = mocks.createMock(HttpServletResponse.class);
expect(request.getRequestDispatcher("/plugins/servlet/timesheet/userislogedin")).andReturn(createMock(RequestDispatcher.class));
    replay(request, response);
    servlet.doGet(request, response);
    verify(request, response);
}

@Test
public void testPost() throws ServletException, IOException {
    HttpServletRequest request = mocks.createMock(HttpServletRequest.class);
    HttpServletResponse response = mocks.createMock(HttpServletResponse.class);
expect(request.getRequestDispatcher("/plugins/servlet/timesheet/userislogedin")).andReturn(createMock(RequestDispatcher.class));
    replay(request, response);
    servlet.doPost(request, response);
    verify(request, response);
}

}

I get this error:

我收到此错误:

Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.046 sec <<< FAILURE!
testPost(com.i4ware.plugin.timesheet.UserIsLogedInServletTest)  Time elapsed: 0.01 sec  <<< ERROR!
 java.lang.NullPointerException
at  com.i4ware.plugin.timesheet.UserIsLogedInServletTest.testPost(UserIsLogedInServletTest.java:67)

testGet(com.i4ware.plugin.timesheet.UserIsLogedInServletTest)  Time elapsed: 0 sec  <<< ERROR!
java.lang.NullPointerException
at com.i4ware.plugin.timesheet.UserIsLogedInServletTest.testGet(UserIsLogedInServletTest.java:58)

回答by Tomasz Nurkiewicz

You need to mock both HttpServletRequestand HttpServletResponseobjects. There are existing implementations, easier to usecompared to standard mocks.

您需要模拟HttpServletRequestHttpServletResponse对象。有现有的实现,与标准模拟相比更易于使用

Once you have request and response instances, you follow this pattern:

一旦你有请求和响应实例,你就遵循这个模式:

private final MyServlet servlet = new MyServlet();

@Test
public void testServlet() {
    //given
    MockHttpServletRequest req = //...
    MockHttpServletResponse resp = //...

    //when
    servlet.service(req, resp);

    //then
    //verify response headers and body here
}

回答by EJK

I am more familiar with Mockito, but I believe they are still similar. In fact I think Mockito was branched from EasyMock a few years back.

我更熟悉 Mockito,但我相信它们仍然相似。事实上,我认为 Mockito 是几年前从 EasyMock 分支出来的。

There is no cookbook approach to unit testing, but this is the basic approach I tend to take:

单元测试没有食谱方法,但这是我倾向于采用的基本方法:

1) Create a real instance of your servlet class (i.e. new MyServlet())

1) 创建 servlet 类的真实实例(即new MyServlet()

2) Create a mock HttpRequest using EasyMock

2) 使用 EasyMock 创建一个模拟 HttpRequest

2a) Mock the desired behavior of the request to simulate a real HTTP request. For example, this may mean you simulate the presence of request parameters or headers.

2a) 模拟请求的所需行为以模拟真实的 HTTP 请求。例如,这可能意味着您模拟请求参数或标头的存在。

3) Create a mock HttpResponse using EasyMock

3) 使用 EasyMock 创建一个模拟 HttpResponse

4) call the doGet() method of your servlet passing it both the mock request and response.

4) 调用 servlet 的 doGet() 方法,将模拟请求和响应传递给它。

5) For verification, inspect the mock HttpResponse. Verify that: (a) the expected methods have been called on the object, (b) The expected data has been passed to the object.

5)为了验证,检查模拟HttpResponse。验证:(a) 已在对象上调用了预期的方法,(b) 已将预期的数据传递给了对象。

I know this is very high-level, but I am just outlining the approach. I assume you know how to accomplish the mocking/verification behaviors using EasyMock.

我知道这是非常高级的,但我只是概述了方法。我假设您知道如何使用 EasyMock 完成模拟/验证行为。

Hope this is helpful.

希望这是有帮助的。

回答by Jason Griebeler

I prefer using spring-test and the MockHttpServletRequest and MockHttpServletResponse. They are more stub like than mocks, but work really well.

我更喜欢使用 spring-test 和 MockHttpServletRequest 和 MockHttpServletResponse。它们比模拟更像存根,但工作得很好。

This answer has information regarding the usage: How to test my servlet using JUnit

此答案包含有关用法的信息:How to test my servlet using JUnit