JUint学习笔记12---对servlet和filter进行单元测试1
来源:互联网 发布:android算法面试题 编辑:程序博客网 时间:2024/06/07 06:15
第三部分 testing components
从JUnit学习笔记1到11都是讲基本的测试尝试,懂得前面的知识,就可以开始Junit in action的最后一程了---测试组件。
第三部分让你把在第一第二部分学到的测试知识实践于J2EE组件。我们将重点学习为各种J2EE组件编写单元测试,并能学习如何用Ant、Maven和Eclipse这些工具进行测试。
第九章 对servlet和filter进行单元测试 Unit-testing servlets and filters
本章内容
- 示范测试驱动开发(TDD)方法
- 用Cactus和mock objects编写servlet和filter的单元测试程序
- 用Maven运行Cactus测试程序
- 选择何时用Cactus,何时用mock objects
介绍管理应用程序
这个示例管理就是目的是要让管理者对关系数据库进行查询。下图就是典型的web应用框架:
(看不到图片的朋友请点这里)
应用程序首先接受用户包含执行SQL查询的HTTP请求。请求被一个安全filter捕获,该安全filter是用来检查SQL查询是否是一个SELECT查询。如果不是,用户将被定向到一个错误的页面,如果查询是一个SELECT语句,那么就将调用AdminServlet。该servlet执行请求的数据库查询,并将结果传送到JSP显示页面。
用Cactus编写servlet测试
在这部分的内容中,我们重点是进行AdminServlet部分执行单元测试。在写代码之前就开始写测试程序叫驱动测试开发或测试先行策略。
先来分析一下AdminServlet的需求,该servlet从Http请求中提取包括将要执行命令的需用参数。然后它将使用提取的命令来获取数据。最后将控制权交给JSP页面来显示穿过来的数据。我们把对应于这些行为的方法分别称为getCommand、executeCommand和callView。
设计第一个测试
下面的代码给出了对getCommand方法的测试。
package junitbook.servlets;import java.util.ArrayList;import java.util.Collection;import java.util.List;import javax.servlet.ServletException;import org.apache.cactus.ServletTestCase;import org.apache.cactus.WebRequest;import org.apache.commons.beanutils.BasicDynaClass;import org.apache.commons.beanutils.DynaBean;import org.apache.commons.beanutils.DynaProperty;public class TestAdminServlet extends ServletTestCase{ public void beginGetCommandOk(WebRequest request) ;测试有效的情况 { ;定义了command request.addParameter("command", "SELECT..."); ;作为Http的参数 } ; ; public void testGetCommandOk() throws Exception ; { ; AdminServlet servlet = new AdminServlet(); ; String command = servlet.getCommand(request); ; ; assertEquals("SELECT...", command); ; } public void testGetCommandNotDefined() ;测试无效的情况,没有定义命令参数 { AdminServlet servlet = new AdminServlet(); try { servlet.getCommand(request); fail("Command should not have existed"); } catch (ServletException expected) { assertTrue(true); } }}
能让TestAdminServlet编译通过的最简单的代码
package junitbook.servlets;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;public class AdminServlet extends HttpServlet{ public String getCommand(HttpServletRequest request) throws ServletException { return null; }}
在你继续其它测试和实现满足测试的最小应用之前,设法运行Cactus测试。虽然是失败的,但是你至少知道为什么会失败。 然后,当你实现测试中的代码时,测试将会成功!
-----------------------------------------------------------------------------------------------
-JUnit最佳实践 记得检验测试在应当失败的时候失败---------------------------------------------------
使用Maven来运行Cactus测试
在前面我们已经学习了使用Cactus/Jetty集成,从一个IDE中来进行Cactus测试。这次,我们将学会使用Maven Cactus插件在Tomcat中进行测试。Tomcat是众所周知的servlet/JSP引擎。Maven Cactus插件是运行Cactus测试最容易的方法之一。所有的事物对于使用者来说都是自动和透明的:你的应用文件war文件的“cactus”化、启动你的容器、配置“cactus”化的war,执行Cactus测试,及停止你的容器。(“cactus化”就是自动附加Cactus jars,并且把Cactus需要的入口附加在你的web.xml文件中)。
默认情况下,Maven Cactus插件在src/testcactus目录下查找Cactus测试程序。我们也需要将所有的元数据和资源文件放在src/webapp目录下。管理应用程序的web.xml文件如下:
1.0" encoding="ISO-8859-1"?>-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> AdminServlet <servlet-class>junitbook.servlets.AdminServletclass> AdminServlet /AdminServlet
要用Maven运行Cactus测试,我们还要提供一个有效的project.xml文件,代码如下,关于细节,在前面的笔记中有描述:
1.0" encoding="ISO-8859-1"?> 3 junitbook-servlets JUnit in Action - Unit-testing servlets and filters 1.0 Manning Publications Co. http://www.manning.com/ http://www.manning.com/front/dance.gif 2002-2003 <package>junitbook.servletspackage> /images/jia.jpg Chapter 9 shows how to unit test Servlets annd Filters using both the Mock Object approach and the in-container approach. It highlights how they complement each other and give strategies on when to use them. Chapter 9 of JUnit in Action: Unit-testing servlets and filters http://sourceforge.net/projects/junitbook/ Vincent Massol vmassol vmassol@users.sourceforge.net Pivolis Java Developer commons-beanutils commons-beanutils 1.6.1 true servletapi servletapi 2.3 easymock easymock 1.0 mockobjects mockobjects-core 0.09 src/java src/test **/Test*.java **/Test*All.java maven-cactus-plugin
- 首先,定义你要运行时需要的jar文件。你不需要包含Cactus相关jar,因为Maven Cactus插件自动包含这些jar。
- Maven Cactus插件使用war文件。元素告诉Maven在生产的成品war中包括Commons BeanUtils jars。成品war已被Maven Cactus插件cactus化。注意因为你将会在你的servlet中使用Commons BeanUtils jars,所以必须包含对BeanUtils的依赖关系。
- 包含/排除纯粹的JUnit测试以匹配你想运行的测试。
- 列出生成的报告。
在运行Cactus插件之前,你要通告Cactus插件,Tomcat被安装在你机器哪个位置,这样才能在能在容器中运行Cactus测试。Cactus插件需要你在你的project.properties文件中增加下面的这一行:
cactus.home.tomcat4x =C:/Apps/jakarta-tomcat-4.1.24
完成Cactus servlet测试
使得测试通过的getCommand实现
package junitbook.servlets;import java.util.Collection;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class AdminServlet extends HttpServlet{ public static final String COMMAND_PARAM = "command"; public String getCommand(HttpServletRequest request) throws ServletException { String command = request.getParameter(COMMAND_PARAM); if (command == null) { throw new ServletException("Missing parameter [" + COMMAND_PARAM + "]"); } return command; } public void callView(HttpServletRequest request) { }}
测试callView方法
在TestAdminServlet中添加如下代码:
private Collection createCommandResult() throws Exception { List results = new ArrayList(); DynaProperty[] props = new DynaProperty[] { new DynaProperty("id", String.class), new DynaProperty("responsetime", Long.class) }; BasicDynaClass dynaClass = new BasicDynaClass("requesttime", null, props); DynaBean request1 = dynaClass.newInstance(); request1.set("id", "12345"); request1.set("responsetime", new Long(500)); results.add(request1); DynaBean request2 = dynaClass.newInstance(); request1.set("id", "56789"); request1.set("responsetime", new Long(430)); results.add(request2); return results; } public void testCallView() throws Exception { AdminServlet servlet = new AdminServlet(); // Set the result of the exection of the command in the // HTTP request so that the JSP page can get the data to // display request.setAttribute("result", createCommandResult()); servlet.callView(request); } public void beginDoGet(WebRequest request) { request.addParameter("command", "SELECT..."); }
public void callView(HttpServletRequest request) { } public Collection executeCommand(String command) throws Exception { throw new RuntimeException("not implemented"); }
public void beginDoGet(WebRequest request) { request.addParameter("command", "SELECT..."); } public void testDoGet() throws Exception { AdminServlet servlet = new AdminServlet() { public Collection executeCommand(String command) throws Exception { return createCommandResult(); } }; servlet.doGet(request, response); // Verify that the result of executing the command has been // stored in the HTTP request as an attribute that will be // passed to the JSP page. Collection results = (Collection) request.getAttribute("result"); assertNotNull("Failed to get execution results from the " + "request", results); assertEquals(2, results.size()); }
使得测试通过的doGet方法
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { try { Collection results = executeCommand(getCommand(request)); request.setAttribute("result", results); } catch (Exception e) { throw new ServletException( "Failed to execute command", e); } }
有两点需要注意,首先,对callView的调用在doGet中没有出现;测试也没有要求。其次executeCommand被调用,将抛出RuntimeException异常,当然你也可以返回null,但是抛出异常是个比较好的做法,如果方法被错误的调用,你也就不会感到任何的惊奇。
- JUint学习笔记12---对servlet和filter进行单元测试1
- JUint学习笔记12---对servlet和filter进行单元测试1
- JUint学习笔记12---对servlet和filter进行单元测试1
- JUnit学习笔记13---对servlet和filter进行单元测试2
- JUnit学习笔记13---对servlet和filter进行单元测试2
- Juint 3学习笔记1
- JUnit学习笔记14---对JSP和taglib进行单元测试1
- JUnit学习笔记14---对JSP和taglib进行单元测试1
- JUnit学习笔记17---对数据库应用程序进行单元测试1
- JUnit学习笔记17---对数据库应用程序进行单元测试1
- Android学习笔记---对应用进行单元测试
- Juint 4学习笔记1--基本配置
- JUnit学习笔记15---对JSP和taglib进行单元测试2
- JUnit学习笔记15---对JSP和taglib进行单元测试2
- 使用cactus实现对servlet进行单元测试
- 使用cactus实现对servlet进行单元测试
- JUnit学习笔记18---对数据库应用程序进行单元测试2
- JUnit学习笔记19---对数据库应用程序进行单元测试3
- iframe 传值问题
- ViewPager onPageChangeListener总结
- Java_Servlet入门教程
- android在特定情况下显示按钮
- Python:BOA 可视开发环境
- JUint学习笔记12---对servlet和filter进行单元测试1
- 关于COM中变体类型VARIANT
- xml标签内容获得迷惑
- C++虚函数的深入理解
- Linux(CentOS)下VSFTP服务的配置
- libgdx 使用particle editor导出文件后在android中载入不显示问题
- MFC中ComboBox的用法
- Oracle 删除用户和表空间
- ibatis与spring的集成