- 浏览: 2446626 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (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 1655这里的观点非常值得探讨, 所有的产品代码就像是一项投资, 有些 ... -
使用Guava Supplier Mock Datetime
2012-02-04 23:35 2752通过下面的例子了解Guava Supplier的用法.在做单元 ... -
对多线程进行测试
2011-07-02 15:31 1366在junit下, 很难对多线程的代码进行测试, 因此需要借助其 ... -
补习一下EasyMock
2010-04-28 09:18 5016最近有时间, 再温习一下easymock相关的东东 http ... -
结合使用Dummy, InjectTo, PartialMock的单元测试
2009-12-24 21:21 1447结合使用Dummy, InjectTo, PartialMoc ... -
使用代码方式运行指定单元测试类及方法
2009-12-17 08:57 1724记一下, 备忘 private void runT ... -
JunitCore
2009-12-15 01:03 0JUnitCore core = new JUnitCore( ... -
修改dbunit的几个bug兼对dbunit进行扩展
2009-12-08 20:51 3166最近在对unitils进行扩展, 主要是数据库这块儿的内容, ... -
让Unitils实现excel下的多数据源支持
2009-12-03 21:02 3910说明:这里的多数据源需要利用spring中配置的多个DataS ... -
unitils中spring module初始化源码解读
2009-12-03 20:32 2623spring module的初始化还算简单, 但是熟悉里面的原 ... -
解决unitils中的dbunit使用spring中定义的多数据源
2009-12-02 20:07 3140最近在研究unitils, dbunit来适应目前的单元测试. ... -
Unitils 学习笔记
2009-11-27 19:44 7732源码部分 EasyMock相关的 有三个注解: Mock ... -
使用classloader自定义测试套件TestSuite
2009-10-21 19:04 2305junit自带了一个suite用来将多个test case放在 ... -
《单元测试之道Java版——使用JUnit》读书笔记
2009-06-09 23:06 3384这个可能是到目前为止 ... -
JunitRunner定制之模仿@Before对属性进行初始化
2009-02-12 21:54 2499在测试的过程中, 会用到一些模拟数据, 希望在每次调用测试方法 ... -
打造自己的单元测试容器——Junit Runner扩展举例
2009-02-05 23:40 6178最近对java的annotation和junit的Runner ... -
junit4源码浅析
2009-02-05 21:12 7312junit3和junit4是两个非常不同的版本, 不能简单的理 ... -
最近单元测试中写的一个Assert
2009-01-15 22:03 2891该类提供的assert方法主要针对数据库的单元测试中, 使用S ... -
用于生成mock模型对象Setter代码工具类
2009-01-12 10:35 1768最近写的一个工具类, 用来生成mock的javabean对象, ... -
JUnit 4新特性笔记
2008-12-11 08:47 2896测试任何可能的错误。 ...
相关推荐
easyMock
EasyMock单元测试的扩展; EasyMock简介(抽象类接口做测试); EasyMock来进行测试;...EasyMock实践指南; EasyMock使用技巧; EasyMock使用简明手册; EasyMock使用说明; EasyMock使用手记; 用Mock object进行隔离测试;
easyMock2.2
EasyMock主要是为测试提供模拟数据,比如你可以模拟HttpServletRequest。
NULL 博文链接:https://bruceliu02.iteye.com/blog/1775446
还在为找不到jar文件烦心吗,不用了到我空间来有你想要的,持续更新。。。 easymock.jar,easymockclassextension.jar
easymock2 EasyMock使用简明手册
easymock 的使用方法简介easymock 的使用方法简介
EasyMock 是一套通过简单的方法对于指定的接口或类生成 Mock 对象的类库,它能利用对接口或类的模拟来辅助单元测试。本文将对 EasyMock 的功能和原理进行介绍,并通过示例来说明如何使用 EasyMock 进行单元测试。 ...
还在为EasyMock使用时出异常而烦恼? 本压缩包包含除了Junit4之外easyMock3.1所用到的所有相关jar包,junit4可自己导入eclipse自带的即可 本压缩包包括: asm.jar cglib.jar objenesis.jar等 其中asm与cglib已兼容,放心...
EasyMock 是一套通过简单的方法对于指定的接口或类生成 Mock 对象的类库,它能利用对接口或类的模拟来辅助单元测试。 Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一些在应用中不容易构造或者比较...
easymock需要用到的包,没有它不行,easymock-3.1.jar
easymockclassextension-3.0.jar org.easymock.classextension.EasyMock.
EasyMock 是一套通过简单的方法对于指定的接口或类生成 Mock 对象的类库,它能利用对接口或类的模拟来辅助单元测试。 Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一些在应用中不容易构造或者比较复杂...
EasyMock 是一套用于通过简单的方法对于给定的接口生成 Mock 对象的类库。它提供对接口的模拟,能够通过录制、回放、检查三步来完成大体的测试过程,可以验证方法的调用种类、次数、顺序,可以令 Mock 对象返回指定...
easymock servlet 单元测试
easymock.jar包
EasyMock 的文档还有简单实例 还有需要的jar包
EasyMock使用教程,快来看看你还有什么秘密没有发现吧!
windows环境部署easymock,有用到的全部文件和安装说明,包换node.js,redis,mongdb,easymock源码