简体   繁体   English

我如何单元测试HTTPServlet?

[英]How do I Unit Test HTTPServlet?

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. 我刚刚使用Google并制作了此代码。

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)

You need to mock both HttpServletRequest and HttpServletResponse objects. 您需要模拟HttpServletRequestHttpServletResponse对象。 There are existing implementations , easier to use compared to standard mocks. 与标准模拟相比, 现有的实现 更容易使用

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
}

I am more familiar with Mockito, but I believe they are still similar. 我对Mockito更熟悉,但我相信它们仍然相似。 In fact I think Mockito was branched from EasyMock a few years back. 事实上,我认为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 (ie new MyServlet() ) 1)创建servlet类的真实实例(即新的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. 2a)模拟请求的期望行为以模拟真实的HTTP请求。 For example, this may mean you simulate the presence of request parameters or headers. 例如,这可能意味着您模拟请求参数或标头的存在。

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. 5)为了验证,检查模拟HttpResponse。 Verify that: (a) the expected methods have been called on the object, (b) The expected data has been passed to the object. 验证:(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. 希望这是有帮助的。

I prefer using spring-test and the MockHttpServletRequest and MockHttpServletResponse. 我更喜欢使用spring-test和MockHttpServletRequest以及MockHttpServletResponse。 They are more stub like than mocks, but work really well. 它们比模拟更像是存根,但工作得很好。

This answer has information regarding the usage: How to test my servlet using JUnit 这个答案包含有关用法的信息: 如何使用JUnit测试我的servlet

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM