easymock中提供了非常多的方法来实现参数匹配,基本能满足一般参数匹配的要求。
我们来具体看一下到底有哪些方法:
(1) 基于基本类型的比较
1. eq(X value)方法, X 可以是boolean,byte,char, double,float,int,long,short,T
有多个重载方法,支持基本类型如boolean, byte,char, double,float,int, long,short,后面会介绍它也支持Object比较。
这个eq()方法的用法直接了当,基本数值直接比较数值,对于非整型的double和float,由于存在精度的问题,因此增加了以下两个方法来指定比较精度。
eq(double value, double delta)
eq(float value, float delta)
2. aryEq(X[] values) X 可以是boolean,byte,char, double,float,int,long,short,T
这个是eq(X value)方法的数组版本,要求比较的两个数组拥有相同的长度,然后每个元素都"相同",即都可以满足eq(X value)方法。
注意到double和float并没有像eq(X value)方法那样提供可以设置精度的重载版本,不知道在数组比较时如何去设置容许精度。
3. gt(X value), lt(X value), X 可以是byte,double,float,int,long,short
这两个方法用于参数的大小匹配,适用于数值型的基本类型如byte,double,float,int,long,short。
4. geq(X value), leq(X value)
类似gt()和lt(),无非是将">"改为">=", "<"改为"<="。
5. anyX(), X可以是Boolean, Byte, Char, Double, Float, Int, Long, Short
这是一个宽松的匹配方法,任何数值都被视为匹配OK。这个方法在我们不介意参数值时特别有用。
(2) 基于对象的比较
1. eq(T value)方法
和基本类型类似,不过对于Object,是通过调用equals()方法来进行比较。
2. same(T value) 方法
和eq()不同,same()是通过比较对象引用来进行比较的。类似java代码中, a.equals(b)和a == b的差别。
3. anyObject() 和 anyObject(Class<T> clazz)
类似基本类型的any***()方法,非常宽松,在我们不介意参数值时使用。
使用方式有三种
(T)EasyMock.anyObject() // 强制类型转换
EasyMock.<T> anyObject() // 固定返回的泛型
EasyMock.anyObject(T.class) // 在参数中指定返回的泛型
4. isA(Class<T> clazz)
和anyObject(Class<T> clazz) 非常,唯一一个差别在于当输入参数为null时,anyObject(Class<T> clazz)返回true而isA(Class<T> clazz) 返回false。
(3) 逻辑计算
easymock支持在参数匹配时进行一些简单的逻辑计算, 如and(), or (), not()。
not()容易理解,取反而已。or()也容易理解,两个匹配方法匹配一个即可。
但是and()方法我没能理解,不知道该怎么用,两个匹配方法同时匹配? 有知道的朋友,还望指教。
此外在参数匹配中,有几个特殊角色,享受的待遇与众不同,easymock为它们提供了专有方法。
1. Comparable
对于实现了Comparable接口的对象,easymock提供了一系列的专用方法来处理,包括eq, gt, lt, geq, leq:
cmpEq(Comparable<T> value)
gt(Comparable<T> value)
lt(Comparable<T> value)
geq(Comparable<T> value)
leq(Comparable<T> value)
这个特殊处理非常合理,本来Comparable接口就提供了比较的功能,在参数匹配时应该容许直接使用。
2. string
由于字符串匹配使用的场景非常多,因此easymock为此也提供了几个常见的参数匹配方法:
contains(String substring)
startsWith(String prefix)
endsWith(String suffix)
find(String regex)
其中contains/startsWith/endsWith是简单的字符串查找,而find()则通过支持正则表达式来提供复杂匹配。
3. null
对于Object匹配,很常见的一个场景就是输入的参数为null,easymock中提供isNull() 和 notNull() 两个方法来完成对null值的匹配。
开发中,经常会遇到下面这种场景,期望输入的参数满足isA()或者容许为null。而直接使用isA(),是不能支持null的,即如果参数为null时isA()会报不匹配。这个不是easymock的bug,而是刻意而为,解决的方法是使用 or(isA(...), isNull(...))或者anyObject()。
service.execute((ClassA) EasyMock.or(EasyMock.isA(ClassA.class), EasyMock.isNull()));
service.execute(EasyMock.anyObject(ClassA.class));