jmock25基本教程Word格式文档下载.docx
《jmock25基本教程Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《jmock25基本教程Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
class
UserManager
{
2.
3.
public
AddressService
addressService;
4.
5.
Address
findAddress(String
userName)
6.
return
addressService.findAddress(userName);
7.
}
8.
9.
Iterator<
Address>
findAddresses(String
10.
addressService.findAddresses(userName);
11.
12.}
我们有一个UserManager,要测试它的方法,但是,UserManager是依赖于AddressService的。
这里我们准备mock掉AddressService。
这个例子的作用在于像一个传统的helloworld一样,给大家一个简明的介绍,可以有一个感觉,jmock可以做什么。
AddressService本身太复杂,很难构建,这个时候,jmock出场了。
1.@Test
2.public
void
testFindAddress()
//
建立一个test上下文对象。
Mockery
context
=
new
Mockery();
生成一个mock对象
final
addressServcie
context
.mock(AddressService.class);
设置期望。
12.
context.checking(new
Expectations()
13.
14.
当参数为"
allen"
的时候,addressServcie对象的findAddress方法被调用一次,并且返回西安。
15.
oneOf(addressServcie).findAddress("
);
16.
will(returnValue(Para.Xian));
17.
18.
});
19.
20.
manager
UserManager();
21.
22.
设置mock对象
23.
manager.addressService
addressServcie;
24.
25.
调用方法
26.
result
manager.findAddress("
27.
28.
验证结果
29.
Assert.assertEquals(Result.Xian,
result);
30.
31.}
那么这里做了什么事情呢?
1首先,我们建立一个test上下文对象。
2用这个mockerycontext建立了一个mock对象来mockAddressService.
3设置了这个mockAddressService的findAddress应该被调用1次,并且参数为"
。
4生成UserManager对象,设置addressService,调用findAddress。
5验证期望被满足。
基本上,一个简单的jmock应用大致就是这样一个流程。
最显著的优点就是,我们没有AddressService的具体实现,一样可以测试对AddressService接口有依赖的其他类的行为。
也就是说,我们通过mock一个对象来隔离这个对象对要测试的代码的影响。
由于大致的流程是一样的,我们提供一个抽象类来模板化jmock的使用。
abstract
TestBase
protected
/**
*
要测试的userManager.
*/
manager;
设置UserManager,并且设置mock的addressService。
private
setUpUserManagerWithMockAddressService()
调用findAddress,并且验证返回值。
@param
userName
expected
期望返回的地址。
31.
32.
assertFindAddress(String
userName,
expected)
33.
address
manager.findAddress(userName);
34.
Assert.assertEquals(expected,
address);
35.
36.
37.
38.
调用findAddress,并且验证方法抛出异常。
39.
40.
assertFindAddressFail(String
41.
try
42.
43.
Assert.fail();
44.
}
catch
(Throwable
t)
45.
Nothing
to
do.
46.
47.
48.
49.
@Test
50.
test()
51.
52.
setUpExpectatioin();
53.
54.
setUpUserManagerWithMockAddressService();
55.
56.
invokeAndVerify();
57.
58.
59.
60.
建立期望。
61.
62.
63.
64.
65.
调用方法并且验证结果。
66.
67.
68.}
这样一来,我们以后的例子中只用关心setUpExpectatioin()和invokeAndVerify()方法就好了。
好了,让我们来看看一个期望的框架。
1.invocation-count
(mock-object).method(argument-constraints);
inSequence(sequence-name);
when(state-machine.is(state-name));
will(action);
then(state-machine.is(new-state-name));
invocation-count调用的次数约束
mock-objectmock对象
method方法
argument-constraints参数约束
inSequence顺序
when当mockery的状态为指定的时候触发。
will(action)方法触发的动作
then方法触发后设置mockery的状态
这个稍微复杂一些,一下子不明白是正常的,后面讲到其中的细节时,可以回来在看看这个框架。
调用一个方法,可以设置它的返回值。
即设置will(action)。
1.@Override
2.protected
setUpExpectatioin()
的时候,addressServcie对象的findAddress方法返回一个Adress对象。
allowing(addressServcie).findAddress("
will(returnValue(Para.BeiJing));
当参数为null的时候,抛出IllegalArgumentException异常。
allowing(addressServcie).findAddress(null);
will(throwException(new
IllegalArgumentException()));
14.}
16.@Override
17.protected
invokeAndVerify()
assertFindAddress("
Result.BeiJing);
assertFindAddressFail(null);
20.}
这里演示了两种调用方法的结果,返回值和抛异常。
使用jmock可以返回常量值,也可以根据变量生成返回值。
抛异常是同样的,可以模拟在不同场景下抛的各种异常。
对于Iterator的返回值,jmock也提供了特殊支持。
生成地址列表
List<
addresses
ArrayList<
();
addresses.add(Para.Xian);
addresses.add(Para.HangZhou);
iterator
addresses.iterator();
的时候,addressServcie对象的findAddresses方法用returnvalue返回一个Iterator<
对象。
allowing(addressServcie).findAddresses("
will(returnValue(iterator));
dandan"
的时候,addressServcie对象的findAddresses方法用returnIterator返回一个Iterator<
will(returnIterator(addresses));
23.}
25.@Override
26.protected
resultIterator
null;
第1次以"
manager.findAddresses("
断言返回的对象。
assertIterator(resultIterator);
第2次以"
调用方法,返回的与第一次一样的iterator结果对象,所以这里没有next了。
Assert.assertFalse(resultIterator.hasNext());
调用方法,返回的是一个全新的iterator。
48.}
50./**
断言resultIterator中有两个期望的Address
51.private
assertIterator(Iterator<
resultIterator)
resultIterator.next();
Assert.assertEquals(Result.HangZhou,
没有Address了。
60.}
从这个例子可以看到对于Iterator,returnValue和returnIterator的不同。
will(new
Action()
@Override
Object
invoke(Invocation
invocation)
throws
Throwable
Para.Xian;
describeTo(Description
description)
22.}
24.@Override
25.protected
Result.Xian);
27.}
其实这里要返回一个Action,该Action负责返回调用的返回值。
既然知道了这个道理,我们自然可以自定义Action来返回方法调用的结果。
而returnValue,returnIterator,throwException只不过是一些Expectations提供的一些static方法用来方便的构建不同的Action。
除了刚才介绍的
ReturnValueAction直接返回结果
ThrowAction抛出异常
ReturnIteratorAction返回Iterator
还有
VoidAction
ReturnEnumerationAction返回Enumeration
DoAllAction所有的Action都执行,但是只返回最后一个Action的结果。
ActionSequence每次调用返回其Actions列表中的下一个Action的结果。
CustomAction一个抽象的Action,方便自定义Action。
举个例子来说明DoAllAction和ActionSequence的使用。
context.check