转:http://www.cnblogs.com/alipayhutu/archive/2012/05/21/2512363.html
基本原则:
- 隔离:这是初衷,也是单元测试的根本要求
- Just Enough:够就行了,别少,但也别多
- Interaction-based:与之相对的,Stub是state-based
- Expection:事先总有期待,期待方法有没有被调用,期待适当的参数,期待调用的次数,甚至期待mock间调用顺序
- 没考虑复用:
- 依赖暴露无遗,尽现测试代码当中:
基本语法:
Step1. record阶段,记录对若干依赖对象的期望
o= EasyMock.createMock(MyAdd.class); //创建Mock对象
EasyMock.expect(o.add(1,1)).andReturn(2); //对mock对象,提出期望
Step2. Replay阶段,创建测试主对象,并添加依赖对象进去
EasyMock.replay(o); //期望设置完毕,进入replay阶段
xxx.set(o);
Step3. Verify阶段,验证测试结果与交互行为
assertEquals(2, o.add(1,1));
assertNotNull();
EasyMock.verify(o); //对mock对象执行验证
友情提示:
1. 既然设了期望,下面(即Step2)就要测到,否则别设置;
2. 参数设了什么,就要传什么;说了返回什么,就要返回什么;
3. 对异常的测试,别忘了(见拓展里2);
4. 以上说的都是,要Mock Interface(非具体Class),那如何Mock Class呢?用法同上Step1-Step3,只是引入的Jar包不同。Mock Interface—org.easymock.*, Mock Class—org.easymock.classextension.*
5. 建议使用3.0及以上版本
6. Mock Interface/Class还是有些限制的:
- 不能mock final方法
- 不能mock static方法
- 不能mock private方法
- 不能mock这些个特殊方法:equals(), toString(), hashCode()
7. EasyMock.createMock(), createNiceMock(), createStrictMock()
EasyMock.createControl(), createNiceControl(), createStrictControl()
(1)不检查调用次序,不检查调用次序&&对于意料之外的调用返回0/null/false,检查调用次序
(2)strict,对于一个对象的方法间检查次序,不同对象的方法间,却没检查。要想检查也可以,用strict control。
(3)createMock(name, Class),带上name这个字段,可以测试执行失败时的异常信息里看到mock对象名称。
8. ……
拓展:
1. 如何指定次数。EasyMock.expect(o.add(1,1)).andReturn(2).times(3);
还有,once(), atLeastOnce(), anyTimes(), times(count), times(min, max)
2. 如何抛出异常。EasyMock.expect(o.add(1,1)).andThrow(new RuntimeException(“add wrongly!”));
3. 如何处理返回void的方法。o.print(); EasyMock.expectLastCall(); 注意1与2也试用于这里。
4. 模拟出一个参数。EasyMock.expect(o.printName(Easymock.isA(String.class))).andReturn(someObject);
还有anyInt(), anyObject(), isNull(), same(), startsWith()
5. 基本类型的比较。eq(), aryEq(X[] array), gt(), lt(), geq(), leq(), anyX()
6. 对象的比较。eq()调equals(),same()调==,anyObject(), isA()
7. 逻辑计算。and(), or(), not()
8. null。or(isA(), isNull())或anyObject
9. 如何partial mock。Service service = EasyMock.createMockBuilder(Service.class).addMockedMethod("needMockMethod").createMock();
10. 如何在运行时返回值或异常。IAnswer接口和andAnswer()方法。
11. 对同一个方法各种调用行为的模拟。
expect(mock.voteForRemoval("Document"))
.andReturn((byte) 42).times(3)
.andThrow(new RuntimeException()).times(4)
.andReturn((byte) -42);
12. ……
学习自:
http://easymock.org/EasyMock3_0_Documentation.html
http://wenku.baidu.com/view/938fc308581b6bd97f19ea62.html