一直在使用easymock作为mock工具,但是easymock有一个一直令我极其恼火的地方:easymock将interface和class的mock区分开,给出了针对interface mock的easyMock和针对class mock的easyMock class extension。两种mock被严格区分开,连jar包都是两个,使用时不能混用,比如不能用easymock (非class extension)来mock class。
这也就算了,最要命的地方是,easyMock和easyMock class extension在使用时,class名是相同的,只是package不同。这会导致一个非常令人抓狂的问题:如果在同一个测试类中,需要同时使用interface mock和class mock,就必须同时使用org.easymock.EasyMock和org.easymock.classextension.EasyMock,由于java import只能import一个,因此另外一个就必须使用全限定名,如:
import org.easymock.EasyMock;
...
Easymock.createMock(...);
org.easymock.classextension.EasyMock.createMock(...);
编码的时候稍有不慎就搞错,代码难写而且难看。很明显,这是一个没有必要的设计,因为使用者通常并不关心mock的是interface还是class。
近日得知easymock已经发布了新的3.0版本,该版本的主要改进就是消除上述的问题,新版本中可以直接mock class,不再强制使用easyMock class extension。
以下是easymock官网 http://easymock.org/ 的发布信息:
010-05-08: EasyMock 3.0 is available. Perform class mocking directly. EasyMock 1 classes removed.
2010-05-08: EasyMock 3.0 Class Extension is available. Now deprecated. Only a proxy over EasyMock to provide backward compatibility.
可以看到为了兼容2.*版本的就有代码,3.0之中还是发布了Class Extension版本,作为旧有的2.*代码和新的3.0之间的代理。不过明确标记为"deprecated"了。
试用了一下,新的3.0版本中,直接使用org.easymock.EasyMock,可以在同一个case中同时混合mock interface和class,使用方式和以往相同。恩,明显感觉使用方便了许多。
顺便做了一下兼容性测试,针对旧有的使用2.*版本的class mock的测试案例,尝试使用两种方法:
1. 不修改原有代码,使用3.0的class extension来保持兼容
代码编译通过,测试案例正常运行。
这个方案适合项目较大时先整体升级,保证测试案例可以运行,后续再逐步转移到3.0版本。
2. 修改原有代码,不再使用class extension
代码只需一个改动,即将原有的org.easymock.classextension.EasyMock 修改为org.easymock.EasyMock,通常只要简单修订import即可。eclipse下简单ctrl + shift + o 一招即可搞定。
两个方法组合使用,就可以平稳的将原有的2.*的测试案例转移到新的3.0版本中。
强烈推荐还在使用easymock 2.*的朋友们升级到3.0版本。