javaEE开发中要对Struts2的Action和Servlet进行单元测试 需要什么技术?

如题所述

Struts2的Action可以很好的进行单元测试;
但Servlet的测试一般来说需要容器的支持,不是像通常的java类的junit测试一样简单. 一般有下面几咱方式:

一.使用HttpUnit测试
二 使用cactus测试
三 使用Jetty作为嵌入式容器测试servlet.
四 使用mock对象,easymock、jmock等。


示例:

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脚本,让测试进行。
 
 
使用该种方法测试的弱点就是:如果要使用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需要容器支持,使得测试不可以自动进行,但是
 
如果使用一个嵌入式的容器,测试就可以自动了。
 
 
三 使用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测试。
 

四 使用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测试。

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-09-18
junit 可以测试Action的

参数官网文档、例子

javaee的简答题
(1)客户端提交一个HttpServletRequest请求(.action或JSP页面)(2)请求被提交到一系列Filter过滤器,如ActionCleanUp和FilterDispatcher等 (3)FilterDispatcher是Struts2控制器的核心,它通常是过滤器链中的最后一个过滤器 (4)请求发到FilterDispatcher后,FilterDispatcher询问ActionMapper是否需要调用某个Action来处...

java开发需要掌握哪些技术?
第一阶段,Java SE基础:Java环境搭建、Java流程控制语句-for循环、switch选择判断、循环嵌套、数组bai拷贝、多维数组、final关键字、构造函数的调用、类的访问权限和路径、面向对象高级特性、Java异常处理、Set,Map,List接口及接口实现类、Java线程、同步阻塞、Java IO流、文件的操作,复制,读写,删除等。

javaee要学哪些内容
javaee要学的内容有:学习JSP\/servlet、学习数据库开发技术、学习其他JavaEE开发技术。1、第一阶段:掌握JavaSE 该阶段是学习JavaEE的入门阶段,也是基础阶段,每个零基础的Java的学习者都必须掌握。需要熟练的掌握Java基础语法,面向对象,常用api,集合框架,I\/O技术,多线程技术以及其他常用技术(网络编程...

java开发工程师必须要学的技术有哪些?
Java Web应用编程,包括 Java Oracle 编程,即JDBC;JavaWeb编程,包括JSP、Servlet,JavaBean;Java应用编程,包括Weblogic、Websphere、Tomcat;以及利用Jbuilder开发Java程序;MVC与Struts,学习业界通用的MVC设计模式和Struts架构;Java B\/S商务项目开发,4~5人一个项目组,项目大小为(25人*工作日左右)高级部分J2ME程序设计,包括...

java软件开发需要学什么(java软件开发需要掌握的知识)
1.?Java基础知识:包括Java语言的基本语法、面向对象编程、异常处理、泛型、集合框架、输入输出等知识点。 2.?数据库:需要学习SQL语言以及关系型数据库的设计与优化,掌握数据库连接池、事务等操作。 3.?Web开发:了解HTTP协议、前端技术(HTML、CSS、JavaScript),并学习使用常用的Web框架如Spring、SpringMVC、MyBatis等...

java开发要学哪些知识和技能呢?
在学习java软件开发的时候第二个阶段要学习的课程主要就是学习项目需求的分析,需要用到的技术点的分析,概要的设计;项目用到的技术点的学习,包括了javai\/0流的处理,socket网络编程,多线程,泛型标准SQL,JDBC等;掌握JUnit单元的测试方法;项目详细设计,项目实现和总结。在学习java软件开发的时候第三个...

java开发都需要学什么
Web开发: 主要是Web开发相关的内容,包括HTML\/CSS\/js(前端页面)、 Servlet\/JSP(J2EE)以及MySQL(数据库)相关的知识。它们的学习顺序应该是从前到后,因此最先学习的应该是HTML\/CSS\/JS(前端页面)。J2EE:你需要学习的是Servlet\/JSP(J2EE)部分,这部分是Java后端开发必须非常精通的部分,因此这...

java开发app需要学会哪些?
Java程式设计基础 面向物件 常用类API 泛型集合 异常处理 IO 多执行绪 网路程式设计 类载入机制与反射 设计模式 2、JavaWeb核心技术 HTTP协议??WEB伺服器TomCat Servlet request与response Cookie与Session JSP 资料库高阶开发 AJAX JavaWEB高阶开发技术 基础加强之框架载入 专案管理 3、核心框架 Struts2 Hibernate ...

javaee课程介绍
第一步:学习JAVA基础,把JAVA基础学好,也就是JAVA SE学好。第二步:正式进入JAVA EE 先学习网页编程的一些基础语言,包括:DHTML,x,再学习JSP技术,学习JSP基础,然后再学习进阶,包括学习当今最流行的几个框架,struts hibernate,spring,学完之后JSP技术也就完了,在这个过程中要认真的理解SERVLET,学完...

java接口开发框架?
Java应用程序接口(JavaAPI)。Java的三大框架是什么? java三大框架是: 1、Struts 为了解决这些问题,出现了Struts框架,它是一个完美的MVC实现,它有一个中央控制类(一个Servlet),针对不同的业务,我们需要一个Action类负责页面跳转和后台逻辑运算,一个或几个JSP页面负责数据的输入和输出显示,还有一个Form类负责传递...

相似回答
大家正在搜