转jMock Cookbook 中文版三

模拟泛型

Java的泛型系统不能够和它的动态反射API很好的工作.对于jMock,这意味着当你模拟泛型时编译器会警告你可能静态类型错误.警告是不正确的.避免它们最好的方法是在模拟对象声明的变量上使用一个注释抑制警告.

例如,下列泛型接口:

public interface Juicer<T extends Fruit> {
    Liquid juice(T fruit);
}

在一个测试中,你需要模拟这个接口,如下:

Juicer<Orange> orangeJuicer = context.mock(Juicer<Orange>.class, "orangeJuicer");
Juicer<Coconut> coconutJuicer = context.mock(Juicer<Coconut>.class, "coconutJuicer");

然而,依照java语法结构这是不正确的.你实际必须写成下列内容:

Juicer<Orange> orangeJuicer = (Juicer<Orange>)context.mock(Juicer.class, "orangeJuicer");
Juicer<Coconut> coconutJuicer = (Juicer<Coconut>)context.mock(Juicer.class, "coconutJuicer");

那些行,虽然在语句结构和语义上都是正确的,但是产生了安全警告.为了避免这些警告,你必须使用@SuppressWarnings注释变量声明:

@SuppressWarnings("unchecked")
Juicer<Orange> orangeJuicer = context.mock(Juicer.class, "orangeJuicer");

@SuppressWarnings("unchecked")
Juicer<Coconut> coconutJuicer = context.mock(Juicer.class, "coconutJuicer");

希望Java未来版本会提高泛型系统使这不是必须的.

使用jMock和ClassImposteriser模拟类

因为jMock使用Java的默认反射能力,所以jMock框架的默认配置仅仅可以模拟接口,不能模拟类.(事实上,我们考虑那对于我们来说是件好事,因为它鼓励设计聚焦在对象之间的通信,而不是静态分类和数据存储.)然而ClassImposteriser扩展类使用CGLIB2.1Objenesis类库来像接口一样创建类的模拟对象.当使用遗留代码工作时对于分解紧耦合类之间的依赖关系是很有用的.

ClassImposteriser创建模拟实例不需要调用模拟类的构造函数.所以带有有参数或调用可覆盖的对象方法的构造函数的类可以被安全的模拟.然而ClassImposteriser不能创建最终类或最终方法的模拟.

如果你想模拟最终类或者最终方法,JDave类库包含了一个反最终(unfinalizer)代理设备,它在JVM加载它们前能够使类变为非最终的. 它们然后就可以通过ClassImposteriser模拟.

来使用ClassImposteriser:

1. 添加jmock-legacy-2.5.1.jar, cglib-nodep-2.1_3.jar 和 objenesis-1.0.jar到你的CLASSPATH.
2. 导入ClassImposterise到你测试类r into the Mockery of your test class:

 1 JUnit 3
 2
 3 import org.jmock.Expectations;
 4 import org.jmock.integration.junit3.MockObjectTestCase;
 5 import org.jmock.lib.legacy.ClassImposteriser;
 6
 7 public class ConcreteClassTest extends MockObjectTestCase {
 8     {
 9         setImposteriser(ClassImposteriser.INSTANCE);
10     }
11
12     ...
13 }
14 JUnit 4
15
16 import org.jmock.Mockery;
17 import org.jmock.Expectations;
18 import org.jmock.integration.junit4.JUnit4Mockery;
19 import org.jmock.lib.legacy.ClassImposteriser;
20
21 @RunWith(JMock.class)
22 public class ConcreteClassTest {
23     private Mockery context = new JUnit4Mockery() {{
24         setImposteriser(ClassImposteriser.INSTANCE);
25     }};
26
27     ...
28 }
29 Other
30
31 import org.jmock.Mockery;
32 import org.jmock.Expectations;
33 import org.jmock.lib.legacy.ClassImposteriser;
34
35 public class ConcreteClassTest extends TestCase {
36     private Mockery context = new Mockery() {{
37         setImposteriser(ClassImposteriser.INSTANCE);
38     }};
39
40     ...
41 }

3.你的测试现在可以创建抽象的或者甚至具体的类的模拟了:

Graphics g = context.mock(java.awt.Graphics.class);

转jMock Cookbook 中文版三

时间: 2024-10-07 18:08:53

转jMock Cookbook 中文版三的相关文章

转jMock Cookbook 中文版二

期望方法多于(少于)一次 入门仅演示了期望对一个模拟对象的一个调用.测试经常需要使用不同基准的期望来允许一些方法调用发生,但如果不发生不会失败,期望方法被调用多次或不是全部,或忽略不相关的拟对象. 一个期望的调用次数定义了期望的这个方法允许被调用最小和最大次数.它在期望中的模拟对象前被指定. invocation-count (mock).method(parameters); ... JMock定义了下列基准: one 调用期望一次且仅一次. exactly(n).of 调用期望正是n次.注意

转jMock Cookbook 中文版一

入门 定义期望 模拟方法的返回值 从模拟方法抛出异常 匹配参数值 精确指定期望参数匹配值 期望方法多于(少于)一次 期望调用顺序 期望一个调用在两个其他调用之间 忽略不相关的模拟对象 在测试的Set-Up中覆盖期望定义 匹配对象和方法 编写新的匹配器 编写新的行为 使用脚本轻松定义行为 使用模拟对象测试多线程代码 模拟泛型 模拟抽象的和实际类 使用非Java语言来使用jMock 更新jMock 1到jMock 2 在Maven构建中使用jMock 理解jMock 2中的方法调度 在Eclipse

python书籍推荐:Python Cookbook第三版中文

所属网站分类: 资源下载 > python电子书 作者:熊猫烧香 链接:http://www.pythonheidong.com/blog/article/44/ 来源:python黑洞网 内容简介 <Python Cookbook(第3版)中文版>介绍了Python应用在各个领域中的一些使用技巧和方法,其主题涵盖了数据结构和算法,字符串和文本,数字.日期和时间,迭代器和生成器,文件和I/O,数据编码与处理,函数,类与对象,元编程,模块和包,网络和Web编程,并发,实用脚本和系统管理,测

python cookbook第三版学习笔记十三:类和对象(三)描述器

__get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法比较绕,我们来看一个实例: class Descriptor(object):     def __get__(self, instance, owner):         return 'get',self,instance,owner class T(object):     d=Descri

python cookbook第三版学习笔记三:列表以及字符串

过滤序列元素: 有一个序列,想从其中过滤出想要的元素.最常用的办法就是列表过滤:比如下面的形式:这个表达式的意义是从1000个随机数中选出大于400的数据 test=[] for i in range(1000):     test.append(random.randint(1,1000)) ret=[n for n in test if n >400] 根据cookbook书上的描述,这个方法适用于小数据的方式.如果数据集非常的大,而且要考虑内存的话建议使用生成器的方式ret=(n for

python cookbook第三版学习笔记六:迭代器与生成器

假如我们有一个列表 items=[1,2,3].我们要遍历这个列表我们会用下面的方式 For i in items:   Print i 首先介绍几个概念:容器,可迭代对象,迭代器 容器是一种存储数据的数据结构,容器将所有数据保存在内存中,典型的容器有列表,集合,字典,字符数组等.如items就是一个列表容器.   可迭代对象:这个对象是否可迭代.如items也是一个可迭代对象.简单来说如果可以用for循环的对象都称为可迭代对象.如果要判断是否是一个可迭代的对象.可以用print isinsta

python cookbook第三版学习笔记十一:类和对象(二)调用父类的方法

在子类中调用父类的方法,可以下面的A.spam(self)的方法. class A(object):     def spam(self):         print 'A.spam' class B(A):     def spam(self):         print 'B.spam'         A.spam(self) if __name__=='__main__':     b=B()     b.spam() 但是上面的代码有一个问题,如果B的父类变更了,而且有很多子类的父

python cookbook第三版学习笔记七:python解析csv,json,xml文件

CSV文件读取: Csv文件格式如下:分别有2行三列. 访问代码如下: f=open(r'E:\py_prj\test.csv','rb') f_csv=csv.reader(f) for f in f_csv:     print f 在这里f是一个元组,为了访问某个字段,需要用索引来访问对应的值,如f[0]访问的是first,f[1]访问的是second,f[2]访问的是third. 用列索引的方式很难记住.一不留神就会搞错.可以考虑用对元组命名的方式 这里介绍namedtuple的方法.

jsoup Cookbook(中文版)--爬虫(java)

转载:http://www.open-open.com/jsoup/ 目录: 入门 解析和遍历一个html文档 输入 解析一个html字符串 解析一个body片断 根据一个url加载Document对象 根据一个文件加载Document对象 数据抽取 使用dom方法来遍历一个Document对象 使用选择器语法来查找元素 从元素集合抽取属性.文本和html内容 URL处理 程序示例:获取所有链接 数据修改 设置属性值 设置元素的html内容 设置元素的文本内容 html清理 消除不受信任的htm