Jmockit用户指南中文翻译(未校对)之二
?声明和使用mock类型
可以通过一个实例属性字段或者参数声明来引入一个Mock类型。在第一种情况,属性字段是属于测试类或者一个mockit.Expectations 子类(一个expectation 期望块的内部的局部属性字段)。第二种情况,参数必须是属于某个测试方法。
在所有情况,一个mock 属性字段或者参数声明,都可以通过使用 mockit.Mocked注解(@Mocked)声明。对于方法mock的参数或者 在expectation 期望块中定义的mock属性字段来说,该注解是可选的。注解@Mocked(或者其他mock的注解类型,例如 @NonStrict)只是对于定义在测试类中的属性字段域才是必须的,这是为了防止和该测试类的其他不需要mock的字段属性产生冲突而已。
Java类型的各种mock属性字段域和参数都是有效的,除了基本类型和数组类型。所以,以下引用类型是有效的:接口,具体的类,抽象类,final类,枚举类型,注释类型。请注意,这包括从JRE的引用类型(属于标准的包之一,例如java.lang,java.util,等等依此类推)。
对于声明在测试方法的参数列表中的mock参数,当调用执行该测试方法时,Jmockit会对该声明类型的参数自动创建一个实例,并通过JUnit/TestNG 测试框架进行传递。因此这个参数值永远不会为null的。
对于mock属性字段域,Jmockit同样会自动创建一个实例,并设置到该属性字段域中,除非该字段域是一个final的域。对于这种情况,需要在测试代码中显式的创建一个值并设置到域中。如果只有构造函数和静态方法将要调用它,那么这个域的值可以是null的,这样对于 mock的类来说也是有效的。
?Mocked 实例最后,我们注意到,使用Jmockit来创建mock实例,其实与使用其他传统的mock工具来创建mock对象是很类似的,但是又不完全一样。对于每一个mock类型实例(无论是使用jmockit或者其他工具来创建),都将被mock模拟了,只要这些类型仍然被mocked。对于传统的mock api来说,只有被mock工具创建的mock实例才真正被mock掉。但在大多数的测试代码编写过程中,这些只是有很少的区别,甚至说,没有任何区别,只是我们需要在脑瓜中记住这些差异就行。
多接口同时mockInjectable mocked实例假设我们需要测试这样的代码:这些代码执行时需要一个给定的类的多个实例。如果我们声明该类被mocked掉,那么这个类的所有实例都会变得一样:他们都变成了mock实例了,因此任何实例的方法调用都会根据我们mock的实现来处理。然而,如果我们只需要这些实例其中某一个(或者某一些)才需要被mock,而其他实例的调用都是执行最原始的真实实现,此时我们该怎样?这就是注解@Injectable 的用武之地了。(它同样有其他的用法,我们稍后会再讨论)。
通过使用注解@Injectable声明一个mock域或者mock参数,我们可以获取一个"独特"的mock实例,而其他同一个 mock类型的实例,会仍然保持原有的未被 mock实例,除非它和一个隔离的mock 域关联在一起。既然一个injectable mocked实例是用来让其他实例保持原始的实现,那么它的静态方法和构造函数同样不会被 mock(译者注:这是很自然的,如果这个特性都保持不了,则没法保证其他实例拥有原始的实现,因为静态方法和构造函数是各个实例共享的)。毕竟一个静态方法并不是和任何一个类实例关联的,而构造函数只是用于来创建实例(只是各实例之间会有所不同而已)。
举一个例子,我们来测试下面的类。
??
。