通过反射准备单元测试数据

(edit by king)在编写单元测试的时候,一般提倡将测试数据和测试代码分离。这样做的好处在于, 测试数据的管理方便,增加和减少测试数据都会相对方便一点。

通常,我们可以模仿junit提供的参数化这样的方法,将测试数据进行分类,变成多个test case。 其中可能会遇到的最大麻烦就是数据准备的格式,和如何通过数据文件,生成测试需要的数据。

我尝试使用xml方式来定义数据,xml的最大好处,就是能够通过标签和属性,自定义各种java的数据类型。 包括基本数据类型(如int, double, boolean等),数组类型,java bean等。 这里就介绍下这些数据类型的创建方法。

java提供了强大的反射机制,能够在运行时根据名称创建需要的对象。这里所有的对象创建都需要用到。 首先,对于基本数据类型,可以发现,通过int.class可以创建int的Class对象,但是却没有办法通过 Class.forName(“int”)来创建这个Class对象。所以,对于创建这种基本数据类型,我是通过对名称的判断, 创建对应的Class对象的。创建代码如下:

[cc lang=’java’ escaped=”true” tab_size=”4″]

private Class<?> getClassName(String valueType) throws ClassNotFoundException {

if (“boolean”.equals(valueType)) {

return boolean.class;

} else if (“char”.equals(valueType)) {

return char.class;

} else if (“int”.equals(valueType)) {

return int.class;

} else if (“long”.equals(valueType)) {

return long.class;

} else if (“short”.equals(valueType)) {

return short.class;

} else if (“byte”.equals(valueType)) {

return byte.class;

} else if (“float”.equals(valueType)) {

return float.class;

} else if (“double”.equals(valueType)) {

return double.class;

} else {

return Class.forName(valueType);

}

}

[/cc]

用前面的代码,能够根据名字创建出对象的Class对象,再通过apache的ConvertUtils, 将Class对象和通过数据文件获取的对象值(String类型),这样就能够创建基本数据类型、数组 和java对象的创建。

ConvertUtils帮我们实现了基本数据类型和它们数组,BeanUtils帮我们创建了需要的java bean。 但是,我们在测试异常数据的时候,往往还需要准备一类特殊的对象——异常。

为了能够不增加标签,我们仍然采用了原来的创建数据的value标签。这样,就需要在原来创建普通对象 的时候,对异常类型进行判断。根据原来的源码,是通过ConvertUtils.convert这个静态方法, 将文本内容和Class对象转换为制定对象的实例。通过对ConvertUtils代码的查看,它内部仅仅对 部分类型,有现成的实现,对于没有注册的类型,只会返回一个String对象。

因此,最方便的扩展方法,就是当Class对象是Exception的扩展类时,向ConvertUtils里面注册一个 转换对象。部分代码如下:

[cc lang=’java’ ]
if(Exception.class.isAssignableFrom(valueTypeClass)) {
ConvertUtils.register(new ExceptionConverter(), valueTypeClass);
}
[/cc]
ExceptionConverter的实现非常简单,如果有内容,则作为异常对象的消息,在构造时传入 (这个应该用处不大,测试的时候,一般只会判断是否有期望的异常抛出)。具体的实现:
[cc lang=’java’ ]

public class ExceptionConverter extends AbstractConverter {

@SuppressWarnings(“unchecked”)

@Override

protected Object convertToType(Class type, Object value) throws Throwable {

if (value instanceof String) {

try {

Constructor c = type.getConstructor(String.class);

return c.newInstance(value);

} catch (Exception e) {

return type.newInstance();

}

}

return type.newInstance();

}

@SuppressWarnings(“unchecked”)

@Override

protected Class getDefaultType() {

return Exception.class;

}

}

[/cc]
在使用过程,还发现了另外一个问题,如果在xml里面采用java的转义字符,digester会自动将 代表转义开始的反斜杠(“\”)进行转义,导致转义字符失效。因为特殊字符也是测试过程中非常用要的 用例,对于这种情况是必须要解决的。

找了半天,用apache commons库里面的StringEscapeUtils进行反转义,来解决这个问题。 用起来非常方便:

[cc lang=’java’ ]
if(valueObject instanceof String) {

valueObject = StringEscapeUtils.unescapeJava((String) valueObject);

}

[/cc]

转载自:https://coolex.info/blog/8.html

时间: 2024-09-20 17:24:01

通过反射准备单元测试数据的相关文章

springboot和mybatis结合

springboot和mybatis结合 依赖和数据源配置 springboot依赖了spring4,需要依赖mybatis-spring,最新版本是1.2.2. 数据源相关的依赖: <!-- datasource --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP-java6</artifactId> <version>${HikariC

让你提前认识软件开发(19):C语言中的协议及单元测试示例

第1部分 重新认识C语言 C语言中的协议及单元测试示例   [文章摘要]         在实际的软件开发项目中,经常要实现多个模块之间的通信,这就需要大家约定好相互之间的通信协议,各自按照协议来收发和解析消息.        本文以实际的程序代码为例,详细介绍了如何用C语言来实现通信协议,并基于对协议字段的判断,说明了程序单元测试的过程,为相关的开发工作提供了有益的参考. [关键词]        软件开发  协议  单元测试  C语言  字段   一.软件模块之间的协议         什么

影响jQuery使用的14个方面_jquery

幸运的是,人们通常具有各种不同的插件可供选择.但是,即使你只用一个,也要弄清楚它是否值得使用的.永远不要在你的代码库中引入错误的代码. 你需要一个插件吗? 首先是要弄清楚究竟你是否需要一个插件.如果不需要,既可以节省文件大小,又可以节省自己的时间. 1.自己写是不是更好? 如果功能很简单,就自己写.jQuery的插件经常会捆绑各种功能,这可能矫枉过正.在这种情况下,手写任何简单的功能往往更有意义.当然,要对所涉及的工作量有所衡量. 举例来说,如果你需要更先进的功能,jQuery UI的手风琴是很

“天眼”FAST落成 配曙光HPC计算“大脑”

9月25日,多个国家和地区的天文科学家和媒体相会贵州平塘,共同见证世界最大射电望远镜-- "500米口径球面射电望远镜"(英文简称FAST)的落成启用仪式.中共中央总书记.国家主席.中央军委主席习近平发来贺信,向参加研制和建设的广大科 技工作者.工程技术人员.建设者表示热烈的祝贺和诚挚的问候.中央政治局委员.国务院副总理刘延东在启用仪式上宣读了习近平的贺信并致辞.为FAST工程 配套高性能计算机的曙光公司,获邀在现场见证了这一历史时刻. 孕育重大天文发现的摇篮 FAST是我国当之无愧的

亲身体验范例框架AppFuse 2.1到底能为Java Web应用开发带来什么?

问题描述 2011年4月4日推出的AppFuse2.1,我已经用它成功地在2周内,开发了一个论坛系统,具备用户注册管理.权限管理.话题-主贴-回帖三级列表与编辑页面.按关键字搜索.列表分页.列表按列排序等功能.期间体验了范例框架开发带来的快速与高效.AppFuse2.1能给你的JavaWeb应用带来的现成的好东西真是太多了,需要分类描述(下面提到的范例源代码指的是AppFuse2.1使用Struts2,Spring3和Hibernate3已经实现好的用户及权限管理模块):1.通用部分1.1pom

springboot和mybatis两个框架结合教程

本文我们来讲讲springboot和mybatis如何结合 依赖和数据源配置 springboot依赖了spring4,需要依赖mybatis-spring,最新版本是1.2.2. 数据源相关的依赖: <!-- datasource --> <dependency>     <groupId>com.zaxxer</groupId>     <artifactId>HikariCP-java6</artifactId>     <

Delphi 2009的反射单元(ObjAuto)

ObjAuto 单元应该算是对 TypInfo 单元的功能扩展吧? 它提供了 5 个方法: GetMethods.GetMethodInfo.CreateMethodPointer.ReleaseMethodPointer.ObjectInvoke 通过 GetMethods.GetMethodInfo 可以获取类公用成员的详细信息. 通过 TypInfo 只能获取 published 区中成员的信息(例子); 通过 ObjAuto 也能获取 public 区的成员信息. 本例效果图: 本例有两

利用Java反射(Reflection) 机制提高代码的行覆盖率

在本文中,您将看到如何通过使用反射机制,在外部直接对目标类中的不可访问成员进行测试,以提高被测代码数量:以及通过修改 Cobertura 源码,使其支持通过正则表达式来过滤不需要进行单元测试的代码,以降低代码总数.代码覆盖率的提高,减少了单元测试过程中未被覆盖的代码数量,降低了http://www.aliyun.com/zixun/aggregation/7155.html">开发人员编写或修改单元测试用例的时间成本,从而提高了整个单元测试的效率. 单元测试是软件开发过程中重要的质量保证环

c#中的反射

目录 反射的概述 反射appDomain 的程序集 反射单个程序集 利用反射获取类型信息 设置反射类型的成员 通过反射创建类型的实例 反射类型的接口 反射的性能 反射的概述 反射的定义:审查元数据并收集关于它的类型信息的能力.元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等,.System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码 和反射相关的命名空间(我们就是通过这几个命