看到有人建议用HttpUnit写servlet的单元测试
http://stackoverflow.com/questions/90907/unit-testing-a-java-servlet
试了一下,测试这么一个servlet
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59package 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测试代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11@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
再试一下:
复制代码
1
2
3
4
5public static void setUpBeforeClass() throws Exception { sr = new ServletRunner(); sr.registerServlet( "checkuser", CheckUserServlet.class.getName() ); sc = sr.newClient(); }
复制代码
这回HTTP容器由HTTPUNIT自己提供,不再需要部署到server,不需要解析html等,所以不再需要依赖第三方JAR了。速度也快了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27@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()); }
这里发现一个问题,例子里的url是
复制代码
我写成
1"http://localhost/PoolEditor"
复制代码
也通过了。试了下
1"http://localhost:8080/checkuser"
复制代码
也可以。而文档里没有提到设置端口。我猜测httpunit的这容器根本没有注册到端口上,它只关心servlet部分的处理.host和port部分不影响测试。
1"http://localhost/checkuser"
另外,如果希望使用web.xml文件来配置servlet,可以用带web.xml和contextPath的ServletRunner。
复制代码
1
2sr = new ServletRunner("webapps/WEB-INF/web.xml","/wanjuan"); sr.registerServlet( "wanjuan", CheckUserServlet.class.getName() );
响应的请求要带上contextPath
复制代码
1
2WebRequest req = new PostMethodWebRequest( "http://localhost:8080/wanjuan/checkuser",is,"application/json");
但是这个带参的ServletRunner被标为deprecation,而且依赖web.xml也不太“单元”。除非用到servlet直接的forward。所以我还是选择不带参的方式。
最后
以上就是矮小裙子最近收集整理的关于用HttpUnit写servlet的单元测试的全部内容,更多相关用HttpUnit写servlet内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复