匹配器
大多数时候期望指定原参数值和调用方法实际参数值做等于比较.例如:
allowing (calculator).add(2,2); will(returnValue(5));
然而有时,你需要定义更加宽松约束给参数值来表达测试目的,或者来忽略那些不相关测试行为的参数,例如:
allowing (calculator).sqrt(with(lessThan(0)); will(throwException(new IllegalArgumentException()); oneOf (log).append(with(equal(Log.ERROR)), with(stringContaining("sqrt"));
宽松的参数约束可以通过为每个参数指定匹配器来定义.通过在上面例子中的lessThan, equal 和 stringContaining工厂方法创建的匹配器 ,来确保期望易读.每个工厂方法结果必须通过一个with方法调用包装.
一个使用参数匹配器的期望必须使用with方法包装每个参数,不管它是匹配器函数还是一个常量值.
通常使用的匹配器工厂方法定义在Expectations类中.更多的匹配器被定义在org.hamcrest.Matchers类的静态方法中.如果你需要它们,静态导入那些匹配器到你的测试代码:
import static org.hamcrest.Matchers.*;
如果需要,匹配器可以联合起来使规范更严紧或者更宽松.匹配器集是可扩展的,所以你可以写新的匹配器来铺盖不常用的测试场景.
基本匹配器
对象相等
最常用的匹配器是equal,它指定被接受的参数必须等于一个给定的值.例如:下列代码指定doSomething方法必须被使用一个为1的参数来调用.
oneOf (mock).doSomething(with(equal(1)));
equalTo约束使用期望值的equals方法来比较期望和实际值相等.Null值会预先被检验,所以指定equal(null)或者应用匹配器给一个null实际值是安全的.数组被视为特殊的例子:两个数组如果它们数量相同,并且所有它们的元素都被认为相等,那么它们被认为相等.
对象相同
same匹配器指定参数实际值必须和期望值是同一对象.它比equal更加严紧,但经常是描述你想要什么参数参考引用行为对象.下列代码指定doSomething方法会使用一个被期望相同对象的参考作为参数来调用.
Object expected = new Object(); oneOf (mock).doSomething(with(same(expected)));
作为经验来说,使用equal给值对象,使用same给行为对象.
子串
stringContaining匹配器指定期望参数必须是一个包含给定子串的字符串. 下列代码指定doSomething方法必须被使用一个包含”hello”文本的字符串参数来调用.
oneOf (mock).doSomething(with(stringContaining("hello")));
stringContaining匹配器对于测试字符串内容并孤立测试与具体的标点符号和格式是特别有用的.例如,上面代码接受下列任何参数值:”hello world”, “hello, world”, “hello!”等.
Null或非Null
aNull(Class)和aNonNull(Class)匹配器分别指定一个参数为null或者非null. 下列代码指定”doSomething”方法必须使用两个字符串调用,第一个参数为null,第二个必须为非null.
oneOf (mock).doSomething(with(aNull(String.class)), aNonNull(String.class)));
任何
any(Class)约束指定任何给定的类型的值都允许.这对于忽略和测试方案不相关的参数很有用.明智的使用any约束确保你的测试很灵活,当测试代码改变时不需要经常维护.下列代码指定”doSomething”方法必须使用两个参数被调用,第一个等于1,第二个在测试中忽略.
oneOf (mock).doSomething(with(eq(1)), with(any(String.class)));
使用误差的数值相等
一个重载版本的equal约束指定浮点值使用一些误差作为舍入误差等于另一个值.下列代码指定”doSomething”方法会使用一个1加或减0.002的值参数被调用.
oneOf (mock).doSomething(with(equal(1, 0.002)));
组合匹配器
匹配器可以组合创建更加严紧或者更加宽松的规范. 组合匹配器本身也是匹配器,因此可以进一步联合.
Not — 逻辑否
not匹配器指定实际参数必须不匹配给定匹配器.下列代码指定”doSomething”方法必须使用一个不等于1的参数调用.
oneOf (mock).doSomething(with(not(eq(1)));
AllOf — 逻辑和
allOf匹配器指定实际参数必须满足给定的所有匹配器作为参数.下列代码指定”doSomething”方法必须使用一个包含”hello”文本和”world”文本的字符串被调用.
oneOf (mock).doSomething(with(allOf(stringContaining("hello"), stringContaining("world"))));
AnyOf — 逻辑或
anyOf匹配器指定实际参数必须满足给定的匹配器中的至少一个作为参数.下列代码指定”doSomething”方法必须使用一个包含”hello”文本或者”howdy”文本的字符串被调用.
oneOf (mock).doSomething(with(anyOf(stringContains("hello"), stringContains("howdy"))));
相关日志
本站文章除特别标示外,其他文章都属于原创内容,转载请按以下格式注明:
本文来源:舞命小丢
原文链接:http://thinking.5ming.org.cn/2008/11/14/jmock-cookbook-matchers/
TrackBack:http://thinking.5ming.org.cn/2008/11/14/jmock-cookbook-matchers/trackback/

[...] 虽然匹配器通常用来指定可接受的参数值,但是它们也可以在期望中,使用类似jMock1的API用来指定可接受对象或方法. 为了做到这一点,在调用次数语句中你通常直接引用一个模拟对象的地方使用一个匹配器.然后链式语句一起来定义期望调用.支持下列语句: [...]
评论时间: 11月 22nd, 2008 at 10:21 上午