- 浏览: 581556 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (188)
- java (14)
- web (14)
- web service (3)
- 杂谈 (14)
- Version Control (13)
- software test (30)
- linux (17)
- database (3)
- distributed storage and computing (1)
- ejb (7)
- project building (46)
- spring & IOC (2)
- Thread (2)
- xml (2)
- tool software (0)
- [网站分类]1.网站首页原创Java技术区(对首页文章的要求: 原创、高质量、经过认真思考并精心写作。BlogJava管理团队会对首页的文章进行管理。) (0)
- project manager (9)
- OSGI (1)
- nosql (3)
最新评论
-
sp42:
好搞笑
你懂不懂xml! (2) -
cherishmmo2004:
感觉你们都很牛掰,我们做的一个运维平台也是用karaf的,用k ...
基于osgi开发大型的企业应用 -
liubey:
“自作聪明”的使用了读写锁,其实只使用ReentrantLoc ...
编码最佳实践(4)--小心LinkedHashMap的get()方法 -
liubey:
你这个代码是sublist后仍然一直持有这个sub的引用,一般 ...
编码最佳实践(5)--小心!这只是冰山一角 -
xiegqooo:
初学maven(5)-使用assembly plugin实现自定义打包
在easymock的使用过程中,当创建mock对象时,我们会遇到 strict mock和nice mock的概念。
比如创建mock对象我们通常使用EasyMock.createMock(),但是我们会发现easymock同时提供了两个类似的方法:
EasyMock.createStrictMock()
类似的在创建MocksControl时,除了通常的EasyMock.createControl() 外,easymock也同时提供两个类似的方法:
EasyMock.createStrictControl()
我们来看看strict和nice有什么作用。参考easymock的javadoc,我们对比createMock()和createStrictMock():
EasyMock.createMock(): Creates a mock object that implements the given interface, order checking is disabled by default.
EasyMock.createNiceMock() : Creates a mock object that implements the given interface, order checking is enabled by default.
发现strict mock方式下默认是开启调用顺序检测的,而普通的mock方式则默认不开启调用顺序检测。
再看一下createNiceMock():
Creates a mock object that implements the given interface, order checking is disabled by default, and the mock object will return 0, null or false for unexpected invocations.
和createMock()相同的是默认不开启调用顺序检测,另外有一个非常有用的功能就是对于意料之外的调用将返回0,null 或者false.之所以说有用,是因为在我们的实际开发过程中,有时候会有这样的需求:对于某个mock对象的调用(可以是部分,也可以是全部),我们完全不介意调用细节,包括是否调用和调用顺序,参数,返回值,我们只要求mock对象容许程序可以继续而不是抛出异常报告说 unexpected invocations 。nice mock在这种情况下可以为我们节省大量的工作量,非常方便。
我们来看一个简单的实际使用的例子,假设我们有一个Business类,依赖于两个service 接口:
先看只调用一个依赖的情况,注意在record阶段service1.method2()和service1.method1()的顺序和business.executeService1()方法中的实际调用顺序是故意设置为不同的。
private Service1 service1;
private Service2 service2;
public void executeService1() {
service1.method1();
service1.method2();
}
public void executeService1And2() {
service1.method1();
service1.method2();
service2.method3();
service2.method4();
}
public void setService1(Service1 service1) {
this.service1 = service1;
}
public void setService2(Service2 service2) {
this.service2 = service2;
}
}
private interface Service1 {
public void method1();
public void method2();
}
private interface Service2 {
public void method3();
public void method4();
}
1. 普通mock
public void testMock() {
Business business = new Business();
Service1 service1 = EasyMock.createMock("service1", Service1.class);
business.setService1(service1);
service1.method2();
EasyMock.expectLastCall();
service1.method1();
EasyMock.expectLastCall();
EasyMock.replay(service1);
business.executeService1();
EasyMock.verify(service1);
}
测试案例可以通过,说明EasyMock.createMock()的确是不检测方法的调用顺序。
2. strict mock
public void testStrictMock() {
Business business = new Business();
Service1 service1 = EasyMock.createStrictMock("service1", Service1.class);
...
}
案例失败,错误信息如下
java.lang.AssertionError:
Unexpected method call service1.method1():
service1.method2(): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
at net.sourcesky.study.easymock.tutorial.$Proxy4.method1(Unknown Source)
at net.sourcesky.study.easymock.tutorial.OrderTest$Business.executeService1(OrderTest.java:14)
at net.sourcesky.study.easymock.tutorial.OrderTest.testStrictMock(OrderTest.java:79)
......
说明strict mock下,easymock检测到了实际调用时的顺序和预期的不同。
3. nick mock
public void testNiceMock() {
Business business = new Business();
Service1 service1 = EasyMock.createNiceMock("service1", Service1.class);
...
}
测试案例可以通过,而且如果是nick mock的话,record阶段可以简化:
public void testNiceMockSimplify() {
Business business = new Business();
Service1 service1 = EasyMock.createNiceMock("service1", Service1.class);
business.setService1(service1);
EasyMock.replay(service1);
business.executeService1();
EasyMock.verify(service1);
}
这个简化版本的测试案例也是可以通过的。
上述的测试案例验证了strict mock和nice mock的基本使用,对于同一个mock对象,strict模式下多个方法之间的调用顺序在record阶段和replay阶段下是需要保持一致的。但是故事并不是到此结束,更有意思的内容在后面:如果出现多个mock对象,那么这些不同mock对象的方法之间,他们的调用顺序是否检测?普通mock和nice mock模式下自然是不会检测顺序,但是strict模式下呢?
我们来看需要测试的方法executeService1And2(),这个方法会依次调用service1和service2的方法。使用easymock测试这个方法,注意我们在record阶段依然故意将方法的调用顺序设置为和实际不同。
1. 不使用control,直接创建两个strict mock对象
public void testWithoutControlInWrongOrder() {
Business business = new Business();
Service1 service1 = EasyMock.createStrictMock("service1", Service1.class);
Service2 service2 = EasyMock.createStrictMock("service2", Service2.class);
business.setService1(service1);
business.setService2(service2);
service2.method3();
EasyMock.expectLastCall();
service1.method1();
EasyMock.expectLastCall();
EasyMock.replay(service1, service2);
business.executeService1And2();
EasyMock.verify(service1, service2);
}
这个测试案例,出于意外的,通过了。easymock并没有检测service1.method1()和service2.method3()这两个方法的调用顺序。
2. 使用strict control创建两个strict mock对象
public void testWithStrictControlInWrongOrder() {
Business business = new Business();
IMocksControl mocksControl = EasyMock.createStrictControl();
...
}
案例失败,错误信息为:
java.lang.AssertionError:
Unexpected method call service1.method1():
service2.method3(): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
at net.sourcesky.study.easymock.tutorial.$Proxy4.method1(Unknown Source)
at net.sourcesky.study.easymock.tutorial.OrderTest$Business.executeService1And2(OrderTest.java:19)
at net.sourcesky.study.easymock.tutorial.OrderTest.testWithStrictControlInWrongOrder(OrderTest.java:218)
......
OK,easymock终于检测到service1.method1()和service2.method3()这两个方法的调用顺序和期望的不一致了。
解释一下,EasyMock.createStrictMock()方法实际上内部是生成一个新的strict control,然后再创建mock对象。
Service1 service1 = EasyMock.createStrictMock("service1", Service1.class);
Service2 service2 = EasyMock.createStrictMock("service2", Service2.class);
这里实际是创建了两个strict control,而easymock是不会跨control进行顺序检测的。在实际使用过程中,我们会有大量的场景需要检测多个mock之间的调用顺序(按说如果没有特殊要求,一般的测试场景默认都应该如此),这种情况下就必须使用control, 而且必须是同一个strict control才能满足要求。
教程后面的最佳实践中有一条就是推荐使用mock control,可以跨mock对象检测方法调用顺序是一个重要原因。
发表评论
-
easymock教程-运行时返回值或者异常
2010-11-30 16:36 5692前面的教程中,我们看到easymock可以通过 ... -
easymock教程-改变同一个方法调用的行为
2010-11-30 17:06 3335在easymock中,对于mock对象的同一个方法,可 ... -
easymock教程-自定义参数匹配器
2010-11-30 18:18 4051虽然easymock中提供了大量的方法来进行参数匹配, ... -
easymock教程-目录
2010-10-14 10:44 8441easymock是目前比较流行的java mock 工 ... -
easymock教程-单元测试中的主要测试对象和依赖
2010-10-14 14:01 3637在单元测试中,通常我们都会有一个明确的测试对象,我们 ... -
easymock教程-record-replay-verify模型
2010-10-15 14:50 7276record-replay-verify 模型容许记录 ... -
easymock教程-easymock的典型使用
2010-10-15 17:14 6184关于easymock的典型使用方式,在easym ... -
easymock教程-class mocking
2010-10-26 16:54 2796前面的例子中,mock的对象都是基于interface ... -
easymock教程-使用MockControl
2010-10-26 17:18 4434在easymock中,通常我们使用一下的代码来创建m ... -
easymock教程-创建stub对象
2010-11-23 17:51 3149前面教程中有个章节讨论到mock和stub的概念差 ... -
easymock教程-mock的限制
2010-11-25 11:12 12210easymock并不是万能的,在使用easymock时 ... -
easymock教程-放宽调用次数
2010-11-29 15:55 3246对于mock对象上的mock方法的调用,easymoc ... -
easymock教程-命名mock对象
2010-11-29 16:34 3036在创建mock对象的时候,我们可以命名mock对象。 ... -
easymock教程-参数匹配
2010-11-29 18:57 7192easymock中提供了非常多的方法来实现参数匹配,基 ... -
easymock教程-partial class mocking
2010-11-30 14:23 2875easymock中提供对于类的mock功能,我们可以方 ... -
easymock教程-mock和stub
2010-08-26 15:26 5905作为测试的基本概念,在开发测试中经常遇到mock和st ... -
推荐升级easymock到新的3.0版本
2010-06-26 20:40 1835一直在使用easymock作为mock工具,但是eas ... -
loadrunner license设置问题
2008-02-18 11:35 7449初学loadrunner,今天准备用这个工具测试一下手头的一个 ... -
TestNG官方文档中文版(1)-介绍
2008-03-18 22:25 1772最近决定开始使用TestNG ... -
TestNG官方文档中文版(2)-annotation
2008-03-19 23:22 1885TestNG的官方文档的中文翻译版第二章,原文请见 http: ...
相关推荐
#### 1.8 easymock教程-strict和nice easymock支持两种类型的mock对象:strict和nice。 - **strict mock**:严格遵循record-replay-verify模型,不允许未预期的方法调用。 - **nice mock**:相对宽松,即使方法...
4. **Nice Mocks 和 Strict Mocks**:EasyMock区分了Nice Mocks和Strict Mocks。Nice Mocks默认允许未预设的方法被调用,而Strict Mocks则会抛出异常,除非所有方法都被明确预设。 5. **Record & Replay 模式**:...
easymock教程 easymock是一种流行的mocking框架,用于单元测试中模拟依赖对象的行为。下面是关于easymock的详细知识点: ### easymock的基本概念 * Mock对象:是一种虚拟对象,模拟真实对象的行为,用于单元测试...
本教程旨在帮助初学者快速掌握Easymock的基本用法和核心概念。 一、Easymock简介 Easymock是一个强大的工具,它提供了对Java接口的模拟支持,让你能在测试环境中模拟对象的行为,返回预设的值。通过模拟,你可以...
##### 1.8 Strict 和 Nice - **Strict Mock**:这种类型的Mock对象会严格遵循定义的行为,如果在测试中出现了未定义的行为,则会抛出异常。 - **Nice Mock**:相比Strict Mock,Nice Mock更加宽松,它允许未定义的...
本教程详细介绍了Easymock的各种特性和使用方法,旨在帮助软件开发人员掌握这一工具。 1. **Mock和Stub的概念** - Mock对象是用于代替真实对象的虚拟对象,它在测试中按照预设的规则来响应调用,帮助验证方法是否...
在压缩包中的"easymock"文件中,可能包含了Easymock的使用教程、源代码示例和相关文档,这些都是深入理解和学习Easymock的好资源。通过阅读这些材料,你可以更好地掌握如何在实际项目中运用Easymock进行单元测试,...
3. **Strict Mocks**:除了Nice Mocks,还有更严格的Strict Mocks。这种类型的模拟对象会检查所有方法的调用,未设置期望的调用将导致测试失败,确保只有预期的行为发生。 4. **Partial Mocks**:在某些场景下,...
Easymock还提供了扩展功能,如Nice Mock和Strict Mock。Nice Mock允许所有未设置期望的方法默认返回默认值,而Strict Mock则会在未设置期望的方法被调用时抛出异常,这有助于发现未覆盖的代码路径。 此外,Easymock...
6. **Nice Mocks 和 Strict Mocks**:Nice Mocks默认允许所有未预期的调用,而Strict Mocks则会抛出异常。可以根据需求选择合适的类型。 7. **控制异常**:你可以设置模拟对象在特定方法调用时抛出异常,如`mock...
除了基本的模拟和期望,EasyMock还提供了更高级的功能,如 Nice Mocks(对未预期的调用返回默认值)、Strict Mocks(对未预期的调用抛出异常)以及Partial Mocks(部分模拟,只模拟部分方法)等。此外,还可以结合...
- **Nice Mocks**:默认情况下,EasyMock创建的模拟对象是Nice Mocks,它们对未预设的行为会返回默认值(如null或0),而不是抛出异常。 - **Strict Mocks**:如果希望模拟对象对每个未预设的方法调用都抛出异常,...
- **Nice Mocks** 和 **Strict Mocks**:Nice Mocks默认允许未预定义的方法调用,而Strict Mocks则不允许。 ### 5. 结合使用其他库 EasyMock可以与其它测试框架如JUnit、TestNG等结合使用,进一步提高测试效率。 #...
7. **Strict和Nice Mocks**: Strict Mocks要求所有预定义的行为都被调用,否则测试失败。Nice Mocks则更为宽容,未被调用的行为不会导致测试失败。 8. **创建Stub对象**: 创建Stub可以设定一个方法总是返回相同...
除了基本的模拟功能,Easymock还提供了扩展功能,如Nice Mock和Strict Mock,它们对模拟对象的行为有不同的约束。Nice Mock允许未预期的方法调用,而Strict Mock则会在遇到未预期调用时立即抛出异常。 在实际应用中...
5. **Strict Mock**:与Nice Mock相反,Strict Mock会严格检查所有调用,如果发现未定义的行为,它会立即抛出异常。 6. **Partial Mock**:部分模拟对象允许你只模拟一部分方法,而其他方法则使用实际的实现。 7. ...
4. **Nice Mocks 和 Strict Mocks**:Nice Mocks默认允许未定义行为,而Strict Mocks会抛出异常,确保测试覆盖所有可能的路径。 **JUnit** JUnit是Java中最广泛使用的单元测试框架之一。它提供了一个简单的API来...