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
How do I Unit Test HTTPServlet?
提问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 HttpServletRequest
and HttpServletResponse
objects. There are existing implementations, easier to usecompared to standard mocks.
您需要模拟HttpServletRequest
和HttpServletResponse
对象。有现有的实现,与标准模拟相比更易于使用。
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