用HttpUnit写servlet的单元测试

6 篇文章 0 订阅

看到有人建议用HttpUnit写servlet的单元测试

http://stackoverflow.com/questions/90907/unit-testing-a-java-servlet

试了一下,测试这么一个servlet

package com.fangjian.wanjuan.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

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

import org.codehaus.jackson.map.ObjectMapper;

import com.fangjian.wanjuan.Factory;
import com.fangjian.wanjuan.business.UserJob;
import com.fangjian.wanjuan.domain.Result;
import com.fangjian.wanjuan.domain.User;

public class CheckUserServlet extends HttpServlet{

	/**
	 * check user's authority
	 */
	private static final long serialVersionUID = 7622529826117490536L;
	PrintWriter pw = null;
	String body = new String();
	UserJob userjob=null;
	
	public CheckUserServlet() throws IOException{
		userjob=new UserJob();
	}
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		pw = resp.getWriter();
		BufferedReader reader = req.getReader();
		String line = null;
		StringBuilder sb = new StringBuilder();
		while ((line = reader.readLine()) != null) {
			sb.append(line);
		}
		body = sb.toString();
		super.service(req, resp);
	}

	/**
	 * request body: user json {name:"abc",password:"123"}
	 * response body:result json {result:"true",info:null}
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
		ObjectMapper mapper=Factory.getObjectMapper();
		User user=null;
		String jsonResult=null;
		try {
			user = mapper.readValue(body, User.class);
			jsonResult=userjob.checkUser(user);
		} catch (IOException e) {
			Result result=new Result(false);
			result.setInfo(e.getMessage()); 
			jsonResult=result.toString();
		}
		pw.write(jsonResult);
		pw.close();
	}
}

功能是post一个json数据,如{name:"abc",password:"123"} 会验证用户,并返回结果如{result:"true",info:null} 

使用了Jackson来在json和Object转换。

Junit测试代码如下:

	@Test
	public void testCheckUserNotExist() throws IOException, SAXException {
		WebConversation wc = new WebConversation();
		User user=new User("abc","123");
		
	    WebResponse   resp = wc.getResponse( req );
	    String josnResp=resp.getText();
	    
	    ObjectMapper mapper=new ObjectMapper();
	   Result result=mapper.readValue(josnResp, Result.class);
	   Assert.assertEquals(false, result.getResult());

	}

这个测试有几个缺点:

1. 每次测试前要部署到http server

2. 需要大量依赖库(解析html,支持javascript等等)

3. 测试速度稍慢。


又看了相关帖(http://stackoverflow.com/questions/53532/unit-testing-servlets)。人家推荐的是http://httpunit.sourceforge.net/doc/servletunit-intro.html

再试一下:

	public static void setUpBeforeClass() throws Exception {
		sr = new ServletRunner();
	    sr.registerServlet( "checkuser", CheckUserServlet.class.getName() );
	    sc = sr.newClient();
	}
	@Test
	public void testCheckUserExistWrongPassword2() throws IOException, SAXException {
		//create user
		UserJob userjob=new UserJob();
		User user=new User("abc","123");
		userjob.createUser(user);
		
		//check user
		User userwrong=new User("abc","1234");
		InputStream is=new ByteArrayInputStream(userwrong.toString().getBytes("utf-8"));
	    WebRequest     req = new PostMethodWebRequest( "http://localhost:8080/checkuser",is,"application/json");
	    WebResponse   resp = sc.getResponse( req );
	    String josnResp=resp.getText();
	    
	    ObjectMapper mapper=new ObjectMapper();
	   Result result=mapper.readValue(josnResp, Result.class);
	   Assert.assertEquals(false, result.getResult());
	}
这回HTTP容器由HTTPUNIT自己提供,不再需要部署到server,不需要解析html等,所以不再需要依赖第三方JAR了。速度也快了。

这里发现一个问题,例子里的url是

"http://localhost/PoolEditor"
我写成

"http://localhost:8080/checkuser"
也通过了。试了下

"http://localhost/checkuser"
也可以。而文档里没有提到设置端口。我猜测httpunit的这容器根本没有注册到端口上,它只关心servlet部分的处理.host和port部分不影响测试。


另外,如果希望使用web.xml文件来配置servlet,可以用带web.xml和contextPath的ServletRunner。

sr = new ServletRunner("webapps/WEB-INF/web.xml","/wanjuan");
	    sr.registerServlet( "wanjuan", CheckUserServlet.class.getName() );

响应的请求要带上contextPath

WebRequest     req = new PostMethodWebRequest( "http://localhost:8080/wanjuan/checkuser",is,"application/json");

但是这个带参的ServletRunner被标为deprecation,而且依赖web.xml也不太“单元”。除非用到servlet直接的forward。所以我还是选择不带参的方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值