关于java单元测试中的伪对象介绍(图)
ReadyGo!技术成就梦想
www.efish.cn
efish
2007-10-8 2:23:56
在单元测试的策略中伪对象被广泛使用。他从测试中分离了外部的不需要的因素并且帮助开发人员专注于被测试的功能。
easymock是一个在这方面很有名的工具,可以在运行时为给定的接口创建伪对象。伪对象的行为可以在测试用例中的执行测试代码之前被定义。easymock基于java.lang.reflect.proxy,他可以根据给定的接口创建动态代理类或者对象。但因为使用proxy使得他有一个天生的缺陷:只能创建基于接口的伪对象。
mocquer是一个类似的工具,但他扩展了easymock的功能能够支持创建类的伪对象。
mocquer介绍
mocquer基于dunamis项目,被用来为特定的类或接口生成动态代理类或对象。为方便使用,他遵循easymock的类和方法的命名规范,只是在内部使用不同的实现方法。
mockcontrol是mocquer项目中最重要的类。他被用来控制伪对象的生命周期和行为定义。这个类中有四类方法。
1、生命周期控制方法:
·public void replay();
·public void verify();
·public void reset();
伪对象在他的生命周期中有三种状态:准备态、工作态、验证态。图1显示了伪对象的生命周期。
figure 1. mock object life cycle
刚开始,伪对象处于准备态,他的表现行为可以在这里定义。replay()将改变伪对象的状态为工作态。在这个状态中所有伪对象的方法调用将会遵循在准备态下定义的行为。在verify()调用后,伪对象就处于验证态。mockcontrol会比较伪对象的预定义行为与实际行为是否匹配。匹配规则依赖于使用的mockcontrol类型,这个会在稍后解释。开发人员可以在需要时调用replay()来重现预定义的行为。而任何状态下调用reset()将会清除状态历史并重置为初始的准备态。
2、工厂方法
·public static mockcontrol createnicecontrol(...);
·public static mockcontrol createcontrol(...);
·public static mockcontrol createstrictcontrol(...);
mocquer提供了三种mockcontrol:宽松的,普通的和严格的。开发人员可以在自己的测试用例中根据测试的内容(测试点)和测试的执行方式(测试策略)选择相应的mockcontrol。宽松的mockcontrol是最随意的,他不关心伪对象中方法调用的顺序,甚至未预期的方法调用,只是返回一个缺省值(依赖于方法的返回值)。普通的mockcontrol比宽松的mockcontrol严格些,未预期的方法调用会导致assertionfailederror异常。严格的mockcontrol是最严格的,如果伪对象在工作态下方法调用的顺序与准备态的不同,就会抛出assertionfailederror异常。下表显示了三种不同mockcontrol的区别。
下面是每一个工厂方法的两个不同版本。
public static mockcontrol createxxxcontrol(class clazz); public static mockcontrol createxxxcontrol(class clazz, class args);
如果类是作为接口来模拟的或者他有一个公共或保护的缺省构造函数,则第一个版本的方法会被使用。否则第二个版本会被用来定义标识和提供参数给期望的构造函数。
例如,假设classwithnodefaultconstructor是一个没有缺省构造函数的类:
public class classwithnodefaultconstructor {
public classwithnodefaultconstructor(int i) {
...
}
...
}
·伪对象获取方法
public object getmock();
每一个mockcontrol包含一个生成的伪对象的引用。开发人员可以使用这个方法取得伪对象并且转换为实际的对象类型。
//get mock control
mockcontrol control = mockcontrol.createcontrol(foo.class);
//get the mock object from mock control
foo foo = (foo) control.getmock();
·行为定义方法
public void setreturnvalue(... value);
public void setthrowable(throwable throwable);
public void setvoidcallable();
public void setdefaultreturnvalue(... value);
public void setdefaultthrowable(throwable throwable);
public void setdefaultvoidcallable();
public void setmatcher(argumentsmatcher matcher);
public void setdefaultmatcher(argumentsmatcher matcher);
mockcontrol允许开发人员定义伪对象的每一个方法的行为。当他在准备态时,开发人员可以调用伪对象的方法。首先规定哪一个调用方法的行为需要被定义。然后开发人员可以使用行为定义的方法之一来定义行为。例如,看一下下面的foo类:
//foo.java
public class foo {
public void dummy() throw parseexception {
...
} public string bar(int i) {
...
} public boolean issame(string[] strs) {
...
} public void add(stringbuffer sb, string s) {
...
}
}
伪对象的行为可以按照下面的方式来定义:
//get mock control
mockcontrol control = mockcontrol.createcontrol(foo.class);
//get mock object
foo foo = (foo)control.getmock();
//begin behavior definition
//specify which method invocation"s behavior
//to be defined.
foo.bar(10);
//define the behavior -- return "ok" when the
//argument is 10
control.setreturnvalue("ok");
...
//end behavior definition
control.replay();
...
mockcontrol中超过50个方法是行为定义方法。他们可以如下分类。
o setreturnvalue()
这些方法被用来定义最后的方法调用应该返回一个值作为参数。这儿有7个使用原始类型作业参数的`setreturnvalue()方法,如setreturnvalue(int i)或setreturnvalue(float f)。setreturnvalue(object obj)被用来满足那些需要对象作为参数的方法。如果给定的值不匹配方法的返回值,则抛出assertionfailederror异常。
当然也可以在行为中加入预期调用的次数。这称为
责任编辑: efish
参与评论
查找更多:
核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级
-
相关文章
java标准单元测试库 junit 4 抢先..
junit 是 java? 语言事实上的 标准单元测试库。junit 4 是该库三年以来最具里程碑意义的一次发布。它的新特..
java开源项目——突破junit的局限
“没有人喜欢bug。”大多数关于单元测试的文章以这句话开篇。的确,我们都希望代码如设计的那样准确地执行,..
jbuilder2005单元测试之junit框架
简单的框架 junit是由erich gamma和kent beck开发的开源测试框架,jbuilder集成了这个框架并对此做了..
用 jython 构建 junit 测试包
开发人员有多种理由决定自动化单元测试。许多人甚至进一步发挥它,自动化这些测试的定位和执行。但是如果想..
junit实施
测试的概念 回归测试框架-junit design by contract refactoring ide对junit的支持 junit简..
用junit框架实现java单元测试
随着软件项目的逐渐增大,软件测试在软件开发中的地位显得越来越重要。如果软件项目没有良好的测试流程,随..
2秒记住本站域名
玩过泡泡龙吗?Readygo?Go! 再加上.Com.Cn的后缀,那就是大名小顶的ReadyGo.com.cn
