动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.Java通信和网络管理.
.JSF是初学者进入Java Web世界的跳.
.再谈谈一些J2ME规范.
.虚拟现实之高级技巧(五).
.Java 的 finalize()用途何在.
.Java中类似于C语言中Sizeof功能实.
.精通ejb【三】.
.一个最简单的servlet.
.Tomcat5.5.9的安装配置.
.Simply Singleton -- part2 By D.
.ScriptEngineMajorVersion 函数.
.使用Java中的Date和Calendar类.
.菜鸟初学Java的备忘录之第一次接.
.eclipse反编译插件Jadclipse介绍.
.Tomcat中通过JNDI配置访问数据库.
.学习Core Java 2 Volume(一)鼠.
.length 属性 (String).
.Java学习:J2ME中的内存泄漏.
.Java开源技术:Eclipse的使用技巧.
.for...in 语句.

运用 DBUnit 进行高效的单元测试

发表日期:2008-1-5 |



  现实系统中通常会有一些具有外部依靠性的对象,这些对象和数据库或者其他对象存在诸多关联。假如我们对这样的对象编写单元和组件级测试的话,可以想象将是非常麻烦的一件事.因为这种外部依靠性的存在,使的我们很难将对象孤立出来进行测试。经常提及的白盒测试法,基本上就是通过控制对象的外部依靠性来达到隔离对象的目的,使的可以操作这些对象的状态和相关行为。
  
  运用 模拟对象(mock objects)
  或者stubs,就是一个控制对象外部依靠性的解决方案。通过隔离那些关联的数据库访问类,象JDBC的相关操作类,对于控制对象外部依靠性将是很有效的。但模拟对象的解决方案对一些非凡的应用系统架构就显得力不从心了,象那些运用了EJB的CMP(container-managed
  persistence)或者 JDO(Java Data
  Objects)的应用系统架构,在这些架构里,数据库的访问对象是在最底层的而且很隐蔽。
  
  由Manuel Laflamme
  编写的开放源代码的DBUnit架构体系,对于控制系统内部的数据库依靠性提供了一个非常不错的解决方案。他答应程序员在整个的测试过程中自由的治理控制数据库的状态,这很重要。利用DBUnit,在测试之前,我们可以给目标数据库植入我们需要的数据集,而且,在测试完毕后,数据库完全能够回溯到测试前的状态。
  
  在很多成功的软件项目中,测试自动化往往是要害的层面。DBUnit答应开发人员创建测试用例代码,在这些测试用例的生命周期内我们可以很好的控制数据库的状态。而且,这些测试用例是很轻易实现自动化的。这样在测试过程中我们无须对它进行人工的干预,为人工干预造成的后果而担心就更没必要了。
  
  简单介绍
  配置使用DBUnit的第一步我们首先需要知道如何生成数据库schema,这个文件是XML格式的,其中包括了数据库的表及相关数据信息。
  
  例如,这里有一个数据库表employee
  ,我们可以用SQL的形式这样将他表示出来。
  
  而且,我们可以看到,一个简单的数据集可以这样表示
  
  在DBUnit中,上面这个表和抽样数据信息可以用XML文件的形式这样表示:
  
  <EMPLOYEE employee_uid='1'
  start_date='2001-11-01'
  first_name='Andrew'
  ssn='xxx-xx-xxxx'
  last_name='Glover' />
  
  这个生成的XML格式的文件可以作为系统所需的所有种子文件(seed
  files)的样本模版.
  
  为相互关联的测试场景创建多个种子文件是一个很有效的策略,就象通过不同的数据库文件来区分隔离数据库状态是一个道理。多种子文件策略可以将我们的测试目标锁定到较小的范围,目标数据可以只针对数据库的表,而不是整个数据库。
  
  为了给目标数据库植入不同的职员记录,我们需要的XML数据文件如下所示:
  <?xml version='1.0' encoding='UTF-8'?>
  
  <dataset>
  <EMPLOYEE employee_uid='1'
  start_date='2001-01-01'
  first_name='Drew' ssn='000-29-2030'
  last_name='Smith' />
  
  <EMPLOYEE employee_uid='2'
  start_date='2002-04-04'
  first_name='Nick' ssn='000-90-0000'
  last_name='Marquiss' />
  
  <EMPLOYEE employee_uid='3'
  start_date='2003-06-03'
  first_name='Jose' ssn='000-67-0000'
  last_name='Whitson' />
  </dataset>
  
  现在,要让DBUnit和我们所需的数据库schema一起工作了,对于程序员来说,我们使用DBUnit进行测试可以有两种选择:通过直接编码方式进行测试或者与Ant结合.
  
  编码方式
  DBUnit框架提供了一个基本的抽象测试用例类,叫做DatabaseTestCase,它是JUnit框架中的基础类TestCase的子类。假如我们使用这个类必须首先实现两个钩子方法(hook
  methods):getConnection()和getDataSet().
  
  方法getConnection()需要返回一个IDatabaseConnection类型的对象,这个对象是一个基于普通JDBC连接的包装类。例如,下面的代码段演示了在mysql数据库环境下,IDatabaseConnection类型连接对象的创建方法。
  
  protected IDatabaseConnection getConnection()
  throws Exception {
  
  Class driverClass = Class.forName("org.gjt.mm.mysql.Driver");
  
  Connection jdbcConnection = DriverManager.getConnection(
  
  "jdbc:mysql://127.0.0.1/hr", "hr", "hr");
  
  return new DatabaseConnection(jdbcConnection);
  }
  
  方法getDataSet()返回一个IDataSet类型对象,其实,说白了,他就是我们先前提到的XML数据的种子文件的另一种表现形式。
  
  protected IDataSet getDataSet() throws Exception {
  return new FlatXmlDataSet(
  new
  FileInputStream("hr-seed.xml"));
  }
  
  有了这两个基本的方法以后,DBUnit就可以按照它预先缺省的行为工作了。DatabaseTestCase类提供了两个fixture(我叫它固件,不知仁兄同意否?)方法来控制测试前和测试后的数据库状态。这两个方法就是:
  getSetUpOperation() 和 getTearDownOperation().
  
  一种高效的实施方案就是让getSetUpOperation()方法执行REFRESH操作,通过这个操作,我们可以用种子文件中的数据去更新目标数据库里的数据。接下来,就是getTearDownOperation(),让他去执行一个NONE操作,也就是什么也不执行。
  
  protected DatabaseOperation getSetUpOperation()
  throws
  Exception {
  return DatabaseOperation.REFRESH;
  }
  
  protected DatabaseOperation getTearDownOperation()
  throws
  Exception {
  return DatabaseOperation.NONE;
  }
  
  还有一种有效的方法就是在getSetUpOperation()方法中执行CLEAN_INSERT操作,这样首先会将目标数据库中与我们提供的种子文件一致的数据删除,然后将我们提供的数据插入到数据库中。这个实施顺序保证了我们对数据库的精确控制。
  
  代码样例
  在一个基于J2EE的人力资源系统中,我们很希望对某个数据操作周期实现测试自动化,这个操作周期包括职员的新增,检索,更新和删除。远程接口定义了下列的业务方法(为了简洁清楚,省略了方法中的throws子句).
  
  //译者注:这里的EmployeeValueObject类型对象,译者认为是代表职员实体信息的对象。
  
  public void  createEmployee( EmployeeValueObject emplVo )
  
  public EmployeeValueObject  getEmployeeBySocialSecNum( String ssn )
  
  public void  updateEmployee( EmployeeValueObject emplVo )
  
  public void  deleteEmployee( EmployeeValueObject emplVo )
  
  测试getEmployeeBySocialSecNum()方法
  需要植入一条数据到目标数据库中,另外,测试deleteEmployee()方法和updateEmployee()方法时,同样也是在先前植入的这条记录的基础上进行。最后,测试类会首先利用createEmployee()方法创建一条记录,同时我们需要校验执行这个方法时,是否会有异常发生。
  
  下面这个DBUnit种子文件,叫做"employee_hr_seed.xml",下面将用到这个文件。
  
  <?xml version='1.0' encoding='UTF-8'?>
  <dataset>
  <EMPLOYEE employee_uid='1'
  start_date='2001-01-01'
  first_name='Drew' ssn='333-29-9999'
  last_name='Smith' />
  <EMPLOYEE employee_uid='2'
  start_date='2002-04-04'
  first_name='Nick' ssn='222-90-1111'
  last_name='Marquiss' />
  <EMPLOYEE employee_uid='3'
  start_date='2003-06-03'
  first_name='Jose' ssn='111-67-2222'
  last_name='Whitson' />
  </dataset>
  
  测试类 EmployeeSessionFacadeTest
  ,需要扩展DBUnit的基础类DatabaseTestCase并且必须提供对getConnection()和getDataSet()方法的实现,在getConnection()方法中将获得与EJB容器初始化时一样的数据库实例,getDataSet()方法负责读取上面提及的employee_hr_seed.xml文件的数据。
  
  
  测试方法相当简单,因为DBUnit已经为我们处理了复杂的数据库生命周期任务。为了测试getEmployeeBySocialSecNum()方法,只需要简单的传递一个存在于种子文件中的社保代码号即可,比如
  "333-29-9999".
  
  //译者注:EmployeeFacade 类型对象,译者认为是代表底层数据库数据的映射体
  
  public void testFindBySSN() throws Exception{
  
  EmployeeFacade facade = //oBTain somehow
  
  EmployeeValueObject vo =
  facade.getEmployeeBySocialSecNum("333-29-9999");
  
  TestCase.assertNotNull("vo shouldn't be null", vo);
  TestCase.assertEquals("should be Drew",
  "Drew", vo.getFirstName());
  TestCase.assertEquals("should be Smith",
  "Smith", vo.getLastName());
  }
  
  为了确保操作周期中的创建职员方法createEmployee()没有问题,我们只需简单的执行一下这个方法,然后校验一下看有没有异常抛出,另外,下一步我们要做的就是在这条新增的记录上进行查找操作,看是否可以找到刚创建的记录。
  
  public void testEmployeeCreate() throws Exception{
上一篇:Java Collections--HashMap深度分析与比较 人气:397
下一篇:你知道 Java 中 float 的取值范围吗 人气:549
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-8-29 oblog v4.6 build 20080827
2008-8-29 ASBLOG v2.5 bulid 080828
2008-8-29 时尚DJ舞曲小偷 v3.1
2008-8-29 仿代码信息分类系统 v1.0 Beta3
2008-8-29 浮梦呓语-个人网站 完整版
2008-8-29 多用户QQ空间Flash播放器
2008-8-29 美思卡企业网站管理系统高级版
2008-8-28 LDV个人相册系统 v1.6.1
2008-8-28 讯时网站管理系统CMS v3.5
2008-8-23 Mini WinMount V0.4
2008-8-23 Vista优化大师3.11正式版
2008-8-23 Wine 1.13
2008-8-23 KlipFolio 5.0 Build 5899-80
2008-8-23 Windows Sysinternals Desktops
2008-8-23 OneTap Movies1.2破解版
2008-8-23 AnnotaterPDF阅读1.1.503 破解版
2008-8-23 SoundMeter分贝测量仪 v1.0汉化破
2008-8-23 iDrum音乐节拍1.0破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | Html转换js | js/vbs加密 | md5加密 | 进制转换
实用工具:汉字翻译拼音 | 符号对照表 | 个税计算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵