- 浏览: 2469491 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (574)
- Book (62)
- Architecture (6)
- Java (39)
- Taobao (41)
- Distributed (4)
- Life (72)
- Database (7)
- Spring (16)
- Photography (15)
- Bicycle (41)
- Test (20)
- jBPM (8)
- Business (12)
- Movie (3)
- Ajax (15)
- Code (7)
- Eclipse (96)
- VIM (2)
- Music (6)
- Groovy (10)
- AutoHotKey (3)
- Dorado (10)
- Maven (7)
- Scrum (5)
- English (20)
- Financial (12)
- OSGi (3)
- Other (4)
- Tool (6)
- Browser (1)
- PPT (1)
- Project Management (4)
- Agile (6)
- Nosql (1)
- Search engine (6)
- Shell (2)
- Open Source (4)
- Storm (10)
- Guava (3)
- Baby (1)
- netty (1)
- Algorithm (1)
- Linux (1)
- Python (2)
最新评论
-
roy2011a:
https://github.com/ebottabi/sto ...
storm的序列化问题及与spring的结合方式 -
roy2011a:
能抗能打 写道哥们儿,你好!能共享下那个storm与sprin ...
storm的序列化问题及与spring的结合方式 -
Alick1:
兄弟,你之前是不是在深圳的正阳公司呆过啊?
storm的ack和fail -
liuleixwd:
先点个赞,写的非常好!有个问题请教下,如果我再bolt里不用e ...
storm的ack和fail -
yao-dd:
solr的facet查询
推荐easymock入门贴:
窥探EasyMock(1)基础使用篇
窥探EasyMock(2)进阶使用篇
关于EasyMock常见的几个问题, 这里(http://ozgwei.blogspot.com/2007/06/easymock2-quirk.html)有几点, 我做个翻译:
★EasyMock在录制的时候最典型的写法:
★如果有个要录制的方法只知道类型不知道具体的值, 可以这样写:
★出现这样的异常:
java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
可能是设置mock方法的期望调用方式时, 既使用了isA的方式来指定参数, 又使用了一个具体值来作为参数
比如这样写:
正确的写法:
★andReturn()只是用于当mock对象的方法需要有返回值的情况下,手动设置这个方法的返回值给调用的测试类的。在本例中methodABC (arguments,……)方法就需要在recorder的时候用andReturn()方法指定返回值给TargetClass。如果对于有返回值的方法不指定其返回值,在测试的时候会抛出”java.lang.IllegalStateException: missing behavior definition for the preceeding method call XXX”异常。
★一般不能这样写:
而应该这样写:
否则会抛出这样的异常:
java.lang.IllegalStateException: matcher calls were not used outside expectations
at org.easymock.internal.RecordState.replay(RecordState.java:72)
at org.easymock.internal.MocksControl.replay(MocksControl.java:57)
at org.easymock.EasyMock.replay(EasyMock.java:1280)
也就是说, 返回值必须给一个具体的值, 而不能只指定返回值类型
★在实用expect来设置mock方法的期望调用方式时, 如果使用到基本类型, 但是又不要基本类型的值, 一般不要这样写:
而应该这样写:
★EasyMock还有一个很让人郁闷的地方, 比如一个方法的参数可能为null, 而你在测试的时候又恰恰传了一个空值, 则这个测试是没法通过的, 会出现类似下面的异常:
这也就要求被测试的方法, 参数不能传递空值.
经过跟踪这个应该是EasyMock的一个bug:
不过这个问题也不是不能绕过, 我用了下面的做法:
后来我问了一下EasyMock开发者Tammo Freese, 看来不是能算一个bug, 他做了如下的回答:
这里录制了两个expect:将null和非空值分开, 但是第二个的返回值注意加上anyTimes(), 因为我的第二种情况会调用多次, 如果两种情况都会调用多次, 则都加上该方法即可, 否则会出现类似下面的异常:
★静态方法是没法用EasyMock进行mock的
★如果需要expect的方法没有返回值, 应该这样写:
先执行mock的要调用的方法, 然后调用EasyMock.expectLastCall().anyTimes();
★如果是对具体类进行mock, 则需要使用org.easymock.classextension.EasyMock去替换org.easymock.EasyMock, 当然这个需要加入对easymockclassextension的引用, 具体使用上则没有区别, 如果采用maven构建工程, 则可以采用下面的写法:
★通常对一个方法进行测试的时候, mock一个对象的情况比较多见, 于是我写了下面的一个比较通用的抽象类:
2012-01 更新:
有时候我们会碰到这样的异常信息:
matcher calls were used outside expectations
后来在网上google了一把, 这里有个说明.
简单的说就是andReturn(xxx)中的xxx不能使用EasyMock.anyObject()这样的方法来指定结果. 但是它没有说解决办法. 这里可以利用andAnswer(), 比如这样写:
潜水的比较多
窥探EasyMock(1)基础使用篇
窥探EasyMock(2)进阶使用篇
关于EasyMock常见的几个问题, 这里(http://ozgwei.blogspot.com/2007/06/easymock2-quirk.html)有几点, 我做个翻译:
★EasyMock在录制的时候最典型的写法:
expect(mockEmployeeRepository.findByFirstNameAndLastName("John", "Doe")).andReturn(employees);
★如果有个要录制的方法只知道类型不知道具体的值, 可以这样写:
expect(mockEmployeeRepository.findBySpecification(isA(EmployeeSearchSpecification.class)) .andReturn(employees);
★出现这样的异常:
java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
可能是设置mock方法的期望调用方式时, 既使用了isA的方式来指定参数, 又使用了一个具体值来作为参数
比如这样写:
expect(mockEmployeeRepository.findByDepartmentAndSpecification("HR", isA(EmployeeSearchSpecification.class)).andReturn(emplooyees);
正确的写法:
expect(mockEmployeeRepository.findByDepartmentAndSpecification(eq("HR"), isA(EmployeeSearchSpecification.class)).andReturn(employees);
★andReturn()只是用于当mock对象的方法需要有返回值的情况下,手动设置这个方法的返回值给调用的测试类的。在本例中methodABC (arguments,……)方法就需要在recorder的时候用andReturn()方法指定返回值给TargetClass。如果对于有返回值的方法不指定其返回值,在测试的时候会抛出”java.lang.IllegalStateException: missing behavior definition for the preceeding method call XXX”异常。
★一般不能这样写:
EasyMock.expect(itemPropertyManager.processPublishOrEditSpu(EasyMock.isA(SpuDO.class), EasyMock.isA(BaseResultDO.class))).andReturn(EasyMock.isA(BaseResultDO.class));
而应该这样写:
EasyMock.expect(itemPropertyManager.processPublishOrEditSpu(EasyMock.isA(SpuDO.class), EasyMock.isA(BaseResultDO.class))).andReturn(null));
否则会抛出这样的异常:
引用
java.lang.IllegalStateException: matcher calls were not used outside expectations
at org.easymock.internal.RecordState.replay(RecordState.java:72)
at org.easymock.internal.MocksControl.replay(MocksControl.java:57)
at org.easymock.EasyMock.replay(EasyMock.java:1280)
也就是说, 返回值必须给一个具体的值, 而不能只指定返回值类型
★在实用expect来设置mock方法的期望调用方式时, 如果使用到基本类型, 但是又不要基本类型的值, 一般不要这样写:
EasyMock.expect( keywordsChecker.checkNormalKeywords(EasyMock .isA(String.class), EasyMock.isA(Long.class), EasyMock.isA(String.class))).andReturn("");
而应该这样写:
EasyMock.expect(keywordsChecker.checkNormalKeywords(EasyMock.isA(String.class), EasyMock.anyLong(), EasyMock.isA(String.class))).andReturn("");
★EasyMock还有一个很让人郁闷的地方, 比如一个方法的参数可能为null, 而你在测试的时候又恰恰传了一个空值, 则这个测试是没法通过的, 会出现类似下面的异常:
引用
java.lang.AssertionError:
Unexpected method call checkFixKeywords(null, 50010815):
checkFixKeywords(isA(java.lang.String), <any>): expected: 1, actual: 0
checkNormalKeywords(isA(java.lang.String), <any>, isA(java.lang.String)): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:45)
Unexpected method call checkFixKeywords(null, 50010815):
checkFixKeywords(isA(java.lang.String), <any>): expected: 1, actual: 0
checkNormalKeywords(isA(java.lang.String), <any>, isA(java.lang.String)): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:45)
这也就要求被测试的方法, 参数不能传递空值.
经过跟踪这个应该是EasyMock的一个bug:
public class InstanceOf implements IArgumentMatcher { private final Class<?> clazz; public InstanceOf(Class clazz) { this.clazz = clazz; } public boolean matches(Object actual) { // 问题在这里: return (actual != null) && clazz.isAssignableFrom(actual.getClass()); // 应该这样写: return (actual == null) || clazz.isAssignableFrom(actual.getClass()); } public void appendTo(StringBuffer buffer) { buffer.append("isA(" + clazz.getName() + ")"); } }
不过这个问题也不是不能绕过, 我用了下面的做法:
EasyMock.expect( keywordsChecker.checkFixKeywords( (String) EasyMock.isNull(), EasyMock.anyLong())) .andReturn(""); EasyMock.expect( keywordsChecker.checkFixKeywords( EasyMock.isA(String.class), EasyMock.anyLong())) .andReturn("").anyTimes();
后来我问了一下EasyMock开发者Tammo Freese, 看来不是能算一个bug, 他做了如下的回答:
引用
this is expected behavior, and it is also documented.
The isA() matcher does the same thing as instanceof , so for null, it returns false.
If you would like to match any Object, use
anyObject()
If you would like to match either Strings or null, use
or(isA(String.class), isNull())
The isA() matcher does the same thing as instanceof , so for null, it returns false.
If you would like to match any Object, use
anyObject()
If you would like to match either Strings or null, use
or(isA(String.class), isNull())
这里录制了两个expect:将null和非空值分开, 但是第二个的返回值注意加上anyTimes(), 因为我的第二种情况会调用多次, 如果两种情况都会调用多次, 则都加上该方法即可, 否则会出现类似下面的异常:
引用
java.lang.AssertionError:
Unexpected method call checkFixKeywords("new test", 50010815):
checkFixKeywords(isA(java.lang.String), <any>): expected: 1, actual: 1 (+1)
checkNormalKeywords(isA(java.lang.String), <any>, isA(java.lang.String)): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:32)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:61)
Unexpected method call checkFixKeywords("new test", 50010815):
checkFixKeywords(isA(java.lang.String), <any>): expected: 1, actual: 1 (+1)
checkNormalKeywords(isA(java.lang.String), <any>, isA(java.lang.String)): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:32)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:61)
★静态方法是没法用EasyMock进行mock的
★如果需要expect的方法没有返回值, 应该这样写:
先执行mock的要调用的方法, 然后调用EasyMock.expectLastCall().anyTimes();
★如果是对具体类进行mock, 则需要使用org.easymock.classextension.EasyMock去替换org.easymock.EasyMock, 当然这个需要加入对easymockclassextension的引用, 具体使用上则没有区别, 如果采用maven构建工程, 则可以采用下面的写法:
<!-- mock 相关 --> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymockclassextension</artifactId> <version>2.2.1</version> </dependency> <!-- mock 相关 end-->
★通常对一个方法进行测试的时候, mock一个对象的情况比较多见, 于是我写了下面的一个比较通用的抽象类:
public abstract class AbstractMockExecutor<T> { protected T mock; /** * @param clazz * @return */ protected T createMock(Class<T> clazz) { mock = EasyMock.createMock(clazz); return mock; } public void execute() throws Exception { record(); EasyMock.replay(mock); invoke(); verify(); } /** * 创建mock对象, 并对要mock的方法进行方法录制, 必须在该方法中手动调用{@link #createMock(Class)}方法.<br> * 该方法的一般做法如下: * * <pre> * createMock(MockClass); * EasyMock.expect(mock.mockMethod(mockArgument...)).andReturn( * mockResult); * BeanObject.setter(mock); * </pre> * * @throws Exception */ protected abstract void record() throws Exception; /** * 调用经过mock之后的执行过程 */ protected abstract void invoke() throws Exception; /** * 验证mock是否正确 */ public void verify() { EasyMock.verify(mock); } }
2012-01 更新:
有时候我们会碰到这样的异常信息:
matcher calls were used outside expectations
后来在网上google了一把, 这里有个说明.
简单的说就是andReturn(xxx)中的xxx不能使用EasyMock.anyObject()这样的方法来指定结果. 但是它没有说解决办法. 这里可以利用andAnswer(), 比如这样写:
final AtomicLong count = new AtomicLong(10000L); EasyMock.expect(db.count()).andAnswer(new IAnswer<Long>() { @Override public Long answer() throws Throwable { return count.getAndIncrement(); } }).times(10);
评论
4 楼
asterisk622
2014-01-07
好文好文,你说的问题很多我都碰到过!
不知道你研究过powermock吗? 更加强大的mock扩展
不知道你研究过powermock吗? 更加强大的mock扩展
3 楼
tosee
2013-09-03
2 楼
飞天奔月
2013-07-03
jayung 写道
被浏览1万多次,竟然木有回复?
潜水的比较多
1 楼
jayung
2013-06-20
被浏览1万多次,竟然木有回复?
发表评论
-
Effective Unit Test:代码面前并非人人平等
2012-02-05 15:38 1702这里的观点非常值得探讨, 所有的产品代码就像是一项投资, 有些 ... -
使用Guava Supplier Mock Datetime
2012-02-04 23:35 2801通过下面的例子了解Guava Supplier的用法.在做单元 ... -
对多线程进行测试
2011-07-02 15:31 1413在junit下, 很难对多线程的代码进行测试, 因此需要借助其 ... -
补习一下EasyMock
2010-04-28 09:18 5046最近有时间, 再温习一下easymock相关的东东 http ... -
结合使用Dummy, InjectTo, PartialMock的单元测试
2009-12-24 21:21 1481结合使用Dummy, InjectTo, PartialMoc ... -
使用代码方式运行指定单元测试类及方法
2009-12-17 08:57 1767记一下, 备忘 private void runT ... -
JunitCore
2009-12-15 01:03 0JUnitCore core = new JUnitCore( ... -
修改dbunit的几个bug兼对dbunit进行扩展
2009-12-08 20:51 3193最近在对unitils进行扩展, 主要是数据库这块儿的内容, ... -
让Unitils实现excel下的多数据源支持
2009-12-03 21:02 3944说明:这里的多数据源需要利用spring中配置的多个DataS ... -
unitils中spring module初始化源码解读
2009-12-03 20:32 2655spring module的初始化还算简单, 但是熟悉里面的原 ... -
解决unitils中的dbunit使用spring中定义的多数据源
2009-12-02 20:07 3172最近在研究unitils, dbunit来适应目前的单元测试. ... -
Unitils 学习笔记
2009-11-27 19:44 7789源码部分 EasyMock相关的 有三个注解: Mock ... -
使用classloader自定义测试套件TestSuite
2009-10-21 19:04 2341junit自带了一个suite用来将多个test case放在 ... -
《单元测试之道Java版——使用JUnit》读书笔记
2009-06-09 23:06 3419这个可能是到目前为止 ... -
JunitRunner定制之模仿@Before对属性进行初始化
2009-02-12 21:54 2542在测试的过程中, 会用到一些模拟数据, 希望在每次调用测试方法 ... -
打造自己的单元测试容器——Junit Runner扩展举例
2009-02-05 23:40 6217最近对java的annotation和junit的Runner ... -
junit4源码浅析
2009-02-05 21:12 7349junit3和junit4是两个非常不同的版本, 不能简单的理 ... -
最近单元测试中写的一个Assert
2009-01-15 22:03 2917该类提供的assert方法主要针对数据库的单元测试中, 使用S ... -
用于生成mock模型对象Setter代码工具类
2009-01-12 10:35 1800最近写的一个工具类, 用来生成mock的javabean对象, ... -
JUnit 4新特性笔记
2008-12-11 08:47 2929测试任何可能的错误。 ...
相关推荐
2. **doc文档**:这部分可能包含了项目的用户指南、开发者指南或设计理念等,帮助开发者更深入地理解EasyMock的工作原理和最佳实践。 3. **示例文档**:这些示例通常是一些简单的代码片段,展示了如何在实际项目中...
《JavaScript模式》由Stoyan Stefanov撰写,这本书探讨了JavaScript编程的各种设计模式和最佳实践,包括函数式编程、对象和类、事件处理、模块化等多个方面。通过学习这本书,读者可以了解到如何有效地组织和优化...
EasyMock 是一个强大的Java模拟框架,它允许开发者在单元测试中创建和控制对象的行为,而无需实际实例化这些对象。...同时,不断探索和理解EasyMock的新特性和最佳实践,将进一步提升你的测试能力。
5. **遵循最佳实践**:遵循单元测试的最佳实践,如使用 Arrange-Act-Assert (AAA) 结构来组织测试代码。 在学习和使用这些工具时,阅读提供的文档非常重要。`EasyMock`的文档会讲解如何创建和配置mock对象,以及...
#### 四、最佳实践 ##### 1.16 命名Mock对象 - **命名Mock对象**:为了提高测试代码的可读性,建议给Mock对象起有意义的名字。 ##### 1.17 使用MockControl - **MockControl**:早期版本的Easymock使用...
7. **最佳实践**: - 优先使用模拟,而非实际的对象。 - 每个测试只测试一个功能点。 - 清晰地定义和验证每个模拟对象的期望。 - 避免过度使用模拟,保持测试的可读性和维护性。 通过阅读“easymock教程.pdf”...
同时,掌握最佳实践和常见陷阱对于高效利用这些工具至关重要。 总之,JUnit和EasyMock是Java开发中不可或缺的工具,它们不仅提高了开发效率,还显著提升了软件的质量。通过理解其核心概念、熟练掌握API使用,以及...
文档还可能包含常见问题解答、最佳实践和示例代码,帮助开发者更好地理解和使用EasyMock。 在使用EasyMock时,首先需要创建一个模拟对象,例如: ```java Mockery context = new Mockery(); MyInterface mock = ...
Unitils 教程 - 单元测试的最佳实践 Unitils 是一个开源的测试库,它提供了一些实用的工具和方法来帮助开发者编写单元测试。本教程将向您展示如何使用 Unitils 来编写单元测试,并介绍一些常见的单元测试技术。 ...
9. **Best Practices**:文档可能还会包含一些最佳实践,如如何编写有意义的测试用例,避免过度模拟,以及如何有效地组织和维护测试代码。 通过学习这份文档,开发者可以掌握使用Easymock进行单元测试的基本技巧,...
**Unitils 示例** Unitils 是一个强大的 Java 单元测试框架,它提供了丰富的功能来...通过深入理解并应用这些概念,我们可以利用 Unitils 示例工程中的最佳实践,提高测试的质量和效率,确保代码的健壮性和可维护性。
建议查阅Easymock的官方文档,确认推荐的Objenesis版本,以确保最佳的兼容性和性能。 总的来说,解决`NoClassDefFoundError`的关键在于理解错误的原因——缺少或版本不匹配的依赖,并采取相应的措施添加或更新缺失...
Apache Camel 支持基于EIP(Enterprise Integration Patterns)的设计,这些模式是集成领域的最佳实践。EIPs提供了许多预定义的解决常见问题的模板,如内容路由器、消息转换器和错误处理策略,使得开发者能够按照...
在压缩包文件 "mock分享 - 副本.pptx" 中,可能包含了Mock技术的详细讲解、最佳实践以及使用特定工具的教程。PPTX文件可能包含幻灯片,每一页可能涵盖了如下内容: 1. **Mock概念介绍**:解释什么是Mock对象,以及...
《PowerMock实战手册》 PowerMock是一个强大的...总的来说,《PowerMock实战手册》将帮助开发者深入理解并掌握PowerMock的使用,通过实例解析和最佳实践,提升单元测试的质量和覆盖率,确保代码的健壮性和可维护性。
2. **学习最佳实践**:书中可能会涵盖如何使用JUnit与其他库(如Mockito、EasyMock等)配合进行模拟测试,以及如何进行测试驱动开发(TDD)。 3. **熟悉测试工具**:可能包含使用Jenkins、Gradle或Maven等工具集成...
11. **总结**:最后,课程会回顾整个PowerMock的学习过程,强调关键点,并给出实际应用中的最佳实践建议。 通过这些实战教程,开发者能够有效地利用PowerMock进行复杂场景的单元测试,提高测试覆盖率,保证代码质量...
标题 "spring 1jar包" 描述的...这个"spring 1jar包"包含的这些库和框架代表了Java开发中的关键技术和最佳实践,它们共同构建了一个完整的开发环境,使得开发者能够利用Spring的强大功能来构建高效、可维护的应用程序。
**PowerMock学习指南** 在Java开发中,单元测试是一项至关重要的任务,它能...在"PowerMock学习指南.pdf"中,你会找到更多关于如何使用PowerMock的详细步骤和示例,包括如何配置、如何模拟各种情况以及最佳实践建议。