给servlet写单元测试的总结

简介: servlet的测试一般来说需要容器的支持,不是像通常的java类的junit测试一样简单, 下面通过对HelloWorld代码的测试阐述了几种servlet测试方法。 被测试的HelloWorld类的代码如下: /** * 被测试的servlet */ import java.
servlet的测试一般来说需要容器的支持,不是像通常的java类的junit测试一样简单,
 
下面通过对HelloWorld代码的测试阐述了几种servlet测试方法。
 
被测试的HelloWorld类的代码如下:
 
/**
 * 被测试的servlet
 */
import java.io.IOException;
 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.cactus.WebRequest;
import org.apache.cactus.server.HttpServletRequestWrapper;
 
public class HelloWorld extends HttpServlet{
 
 public void saveToSession(HttpServletRequest request) {
         request.getSession().setAttribute("testAttribute",request.getParameter("testparam"));
 }
 
 public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
         String username=request.getParameter("username");
         response.getWriter().write(username+":Hello World!");
       
 }
 
 public boolean authenticate(){
        
        return true;
 
 }
}
 
以HelloWorld为例,我总结了Servlet的多种测试方法如下:
 
一.使用HttpUnit测试
 
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.servletunit.InvocationContext;
import com.meterware.servletunit.ServletRunner;
import com.meterware.servletunit.ServletUnitClient;
import junit.framework.Assert;
import junit.framework.TestCase;
 
public class HttpUnitTestHelloWorld extends TestCase {
 
 protected void setUp() throws Exception {
  super.setUp();
 }
 
 protected void tearDown() throws Exception {
  super.tearDown();
 }
 
 public void testHelloWorld() {
 
  try {
   // 创建Servlet的运行环境
   ServletRunner sr = new ServletRunner();
   // 向环境中注册Servlet
   sr.registerServlet("HelloWorld", HelloWorld.class.getName());
 
   // 创建访问Servlet的客户端
   ServletUnitClient sc = sr.newClient();
   // 发送请求
   WebRequest request = new GetMethodWebRequest(" http://localhost/HelloWorld");
   request.setParameter("username", "testuser");
   InvocationContext ic = sc.newInvocation(request);
   HelloWorld is = (HelloWorld) ic.getServlet();
 
   // 测试servlet的某个方法
   Assert.assertTrue(is.authenticate());
   // 获得模拟服务器的信息
   WebResponse response = sc.getResponse(request);
   // 断言
   Assert.assertTrue(response.getText().equals("testuser:Hello World!"));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
}
 
上述例子其实是junit的一个测试例子,在其中使用了httpunit模拟的servlet环境,使用上述方法测试
 
servlet可以脱离容器,容易把该测试写入ant或maven脚本,让测试进行。
 
httpunit网址: http://httpunit.sourceforge.net/
 
使用该种方法测试的弱点就是:如果要使用request(response)的setCharercterEncoding方法时,测试会出现一些问题,
 
而且httpunit在测试servlet行为时,采用的是完全模拟浏览器,有时测试比较难写。
 
二 使用cactus测试
 
/**
 * cactus测试servlet的例子
 * 必须要有tomcat的支持
 *
 */
 
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
import org.apache.cactus.WebResponse;
public class CactusHelloWorld extends ServletTestCase{
 
     HelloWorld servlet;
     public CactusHelloWorld(String theName) {
         super(theName);
     }
 
     protected void setUp() throws Exception {
         super.setUp();
         servlet = new HelloWorld();
     }
 
     protected void tearDown() throws Exception {
         super.tearDown();
     }
 
     /**
      * 测试方法测试参数在此设置
      *
      * @param webrequest
      */
 
     public void beginSaveToSessionOK(WebRequest request) {
         request.addParameter("testparam", "it works!");
     }
    
     /**
      * 测试方法测试参数在此设置
      *
      * @param webrequest
      */
 
     public void beginDoGet(WebRequest request) {
         request.addParameter("username", "testuser");
     }
 
     /**
      * 调用servlet的测试方法
      * 
      */
     public void testSaveToSessionOK() {
         servlet.saveToSession(request);
         assertEquals("it works!", session.getAttribute("testAttribute"));
     }
 
     public void testDoGet() {
         try {
             servlet.doGet(request, response);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 
     /**
      * 此方法可以判断测试方法的输出,会传递测试方法的reponse给end***,并且格式化为cactus
      * 的WebResponse或者可以跟httpunit集成,格式化为httpunit的response
      *
      * @param response
      */
     public void endDoGet(WebResponse response) {
         String content;        
         content = response.getText();
         assertEquals("testuser:Hello World!", content);
     }
}
 
cactus具备丰富灵活的测试功能,如要测试doGet方法,分为beginDoGet(模拟测试参数设置)、DoGet(执行测试)、endDoGet(状态结果验证)
 
相比httpunit来说,写测试更为容易,测试servlet更为专业,流程更为清晰,但是cactus需要容器支持,使得测试不可以自动进行,但是
 
如果使用一个嵌入式的容器,测试就可以自动了。
 
cactus是一个servlet和jsp的测试框架:http://jakarta.apache.org/cactus/getting_started.html
 
三 使用Jetty作为嵌入式容器测试servlet.
 
/**
 * 一个关于嵌入式jetty测试的例子,jetty作为stubs的一个例子
 *
 */
package com.easyjf.testexample;
 
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.servlet.ServletHandler;
 
import com.meterware.httpunit.WebClient;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse;
 
import junit.framework.Assert;
import junit.framework.TestCase;
 
public class JettySampleTest extends TestCase {
 
 Server server;
 protected void setUp() throws Exception {
      //通过代码设置并启动一个服务器,该服务器是servlet的测试容器
      super.setUp();
      server = new Server();
      Connector connector=new SocketConnector();
      connector.setPort(80);
      server.setConnectors(new Connector[]{connector});
      ServletHandler handler=new ServletHandler();
      server.setHandler(handler);
      handler.addServletWithMapping("HelloWorld", "/");
      server.start();
 }
 
 protected void tearDown() throws Exception {
  super.tearDown();
  server.stop();
 }
 
 public void testHellWorld() {
  try {
   WebConversation wc = new WebConversation();
   WebResponse web = wc.getResponse(" http://127.0.0.1/HelloWorld");
   String result=web.getText();
   Assert.assertEquals(result,"it works!");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
 
可以发现,jetty可以充当一个servlet的容器,方便的是,jetty支持嵌入式服务,即可以通过代码来启动,
 
所以要写自动测试的例子很方便,可以结合httpunit或者cactus进行servlet测试。
 
jetty主页: http://docs.codehaus.org/display/JETTY/Embedding+Jetty

四 使用mock对象,此处使用easymock
 
import java.io.PrintWriter;
import java.io.Writer;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import junit.framework.Assert;
import junit.framework.TestCase;
import static org.easymock.EasyMock.*;
public class MockTestServlet extends TestCase {
 
    public void testService() throws Exception {
        System.out.println("service");
        HttpServletRequest request = createMock(HttpServletRequest.class);
        HttpServletResponse response = createMock(HttpServletResponse.class);
        //Creating the ServletConfig mock here
        ServletConfig servletConfig = createMock(ServletConfig.class);
        //Creating the ServletContext mock here
        ServletContext servletContext = createMock(ServletContext.class);
       
        //Create the target object 
     
        HelloWorld4 instance = new HelloWorld();
        //初始化servlet,一般由容器承担,一般调用servletConfig作为参数初始化,此处模拟容器行为
        instance.init(servletConfig);
 
        //在某些方法被调用时设置期望的返回值,如下这样就不会去实际调用servletConfig的getServletContext方法,而是直接返回
 
        //servletContext,由于servletConfig是mock出来的,所以可以完全控制。
        expect(servletConfig.getServletContext()).andReturn(servletContext).anyTimes();
        expect(request.getParameter("username")).andReturn("testuser");
        PrintWriter pw=new PrintWriter(System.out,true);
        expect(response.getWriter()).andReturn(pw).anyTimes();
       
        //以上均是录制,下面为重放,该种机制为easymock测试机制,要理解请看easymock测试的一些资料
        replay(request);
        replay(response);
        replay(servletConfig);
        replay(servletContext);
 
        instance.doGet(request, response);
        pw.flush();
       
 
        //验证结果是否预期,如果预期,则会在pw上写出testuser.
        verify(request);
        verify(response);
        verify(servletConfig);
        verify(servletContext);
   }
}
 
mock测试注重行为,mock对象其实都是模拟的对象,方法一般直接给出一个返回值,没有具体的对象逻辑,mock对象
 
是用来帮助测试要测试的类的。比如要测试servlet的内部行为,又不想要容器等环境,就可以采用mock测试。
 
easymock是mock测试的一个框架: http://www.easymock.org/

本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/cz_hyf/archive/2007/02/10/1507211.aspx
目录
相关文章
|
Java 应用服务中间件 Linux
HTTPS && Tomcat && Servlet && 博客系统 && 软件测试的概念 && Linux
HTTPS && Tomcat && Servlet && 博客系统 && 软件测试的概念 && Linux
57 0
|
Java 测试技术 Maven
一次单元测试优化的过程总结
本文将介绍淘宝用户运营平台团队最近在实践单元测试过程中遇到的一个问题。
416 0
一次单元测试优化的过程总结
|
测试技术 监控 NoSQL
提升单元测试体验的利器--Mockito使用总结
为神马要使用Mockito?   在编写单元测试的时候,为了尽可能的保证隔离性,我们时常需要对某些不容易构造或者不容易获取或者对外部环境有依赖的对象,用一个虚拟的对象来创建以便于测试.假设你正在开发的的代码中使用到了公司其他部门的接口(通过RPC服务),当编写单元测试的时候你可能为了不让接口真的去调...
1511 0
|
Web App开发 测试技术 iOS开发
servlet redirect/forward/session/cookie 与 HTTP 协议的测试
 本文直接展示servlet的测试结果。   servlet的代码中使用sendRedirect:    public class SessionTest extends HttpServlet { protected void...
955 0
|
Java 测试技术 数据格式
单元测试框架TestNg使用总结
工欲善其事,必先利其器 单元测试的重要性是不言而喻的。但如果没有好的单元测试工具,是无法激起开发人员的欲望。 Testng便是利器之一。TestNG是基于Annotation的测试框架的先驱,他拥有通过添加诸如灵活的装置、测试分类、参数测试和依赖方法等特性来克服JUnit3的一些不足之处。
1146 0
|
5天前
|
测试技术 开发者 UED
探索软件测试的深度:从单元测试到自动化测试
【10月更文挑战第30天】在软件开发的世界中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的不同层次,从基本的单元测试到复杂的自动化测试,揭示它们如何共同构建一个坚实的质量保证体系。我们将通过实际代码示例,展示如何在开发过程中实施有效的测试策略,以确保软件的稳定性和可靠性。无论你是新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
3月前
|
JSON Dubbo 测试技术
单元测试问题之增加JCode5插件生成的测试代码的可信度如何解决
单元测试问题之增加JCode5插件生成的测试代码的可信度如何解决
51 2
单元测试问题之增加JCode5插件生成的测试代码的可信度如何解决