MockObjects的选择:EasyMock与JMock的比较

原创 2004年06月04日 11:55:00

MockObjects的选择:EasyMockJMock的比较

本文假设读者已经了解了MockObjects的使用目的和基本方式,不对MockTest之类的技术作过多解释。仅提醒一句:不要测试你的MockObjects”

本文作为一个评测结果的同时,也可以作为EasyMockjMock的简短教程。他们本身都很易用,可惜带的示例过于复杂,都用了过多的模式。看过本文的例子,相信就可以从容的在项目中使用了。

Java中常用的MockObjectsEasyMockjMock等。其中EasyMock开发较早,已经出了1.1版本,而jMock前几天才刚推出了1.0 final。作为刚成熟的小弟弟,jMock有什么竞争实力呢?

本比较针对于以下几个方面,代码请见附件。

1 是否能够对具体类进行模拟(当然,对接口模拟是基本功能)

2 是否能够对方法名,参数,返回值进行动态控制

3 基本代码行数

4 是否能够对具有构造参数的具体类模拟

    现在比较开始了。首先制作若干测试文件,很简单。要模拟的有一个接口和一个具体类,叫做TheInterfaceToMockTheClassToMock,另外,提供方法SampleReturn sampleMethod(Parameter p);以及同名无参数方法。

    第一个测试是针对TheInterfaceToMock,提供ParameterImplSampleReturnImpl作为期待的参数和返回值。

    jMock代码如下:  

public class JMockUsage extends MockObjectTestCase {

    public void testReturnValueWithParemeter(){       

        // 构造Mock控制器

        Mock m = new Mock(TheInterfaceToMock.class);

        // 这是要测试MockObject

        TheInterfaceToMock mock = (TheInterfaceToMock) m.proxy();

        // 期待的返回值

        SampleReturn sr = new SampleReturnImpl();

        // 期待的参数

        Parameter p = new ParameterImpl();

       

        // 控制器,期待一次,方法sampleMethod,参数等于p(equals),将返回sr

        m.expects(once()).method("sampleMethod")

.with(eq(p)).will(returnValue(sr));

              

        // 正式执行mockobject

        SampleReturn ret = mock.sampleMethod(new ParameterImpl());

        // 确定返回值是相同的

        assertSame(sr,ret);

    }

 

}

 

相同功能的easyMcok代码如下:

public class EasyMockUsage extends TestCase {

    public void testReturnValueWithParameter(){       

        // 构造mock控制器

        MockControl control

 = MockControl.createControl(TheInterfaceToMock.class);

        // 这是要测试的MockObject

        TheInterfaceToMock mock

 = (TheInterfaceToMock) control.getMock();

        // 这是要返回的值

        SampleReturn sr = new SampleReturnImpl();

        // 这是要传入的参数

        Parameter p = new ParameterImpl();

       

        // 恢复到记录(record)状态

        control.reset();

        // 首先记录sampleMethod方法

        mock.sampleMethod(p);

        // 设定该方法的返回值

        control.setReturnValue(sr);

        // 切换状态为回复(reply)

        control.replay();       

        // 正式执行mock object的方法,明显的,参数值是equals而不是same

        SampleReturn ret = mock.sampleMethod(new ParameterImpl());

       

        // 确定返回值是需要的值

        assertSame(sr,ret);      

    }

    从上面的代码可以看到,同样的功能,二者的行数相差3行。其主要原因,就是easyMcokMock机制是基于状态,首先是录制状态,记录下来待测的方法和参数,返回值等,然后切换为回复状态。而jMock没有切换这一步,直接将参数返回值用一句话写出来。确实是一句话:期待一次,方法sampleMethod,参数等于p(equals),将返回sr。其中的一些辅助函数,例如returnValue,eq等等,位于父类MockTestCase

    结论

 

    1 如果不能提供MockTestCase作为父类,请使用EasyMock

    2 如果需要批量或动态生成测试,请使用更规则的jMock

    3 如果喜欢看起来行数少一些,请用jMock

    4 如果对状态切换看不顺眼,请用Mock

 

    下面进行具体类测试,一个共同的点是,二者均使用了CGLIB作为增强器,因此效率差别几乎没有。将上面的测试稍稍修改,将TheInterfaceToMock改为TheClassToMock。发生了以下变化。

    jMock,需要将import替换为新的import,代码中其他部分完全不变!

原来

import org.jmock.Mock;

import org.jmock.MockObjectTestCase;

改为:

import org.jmock.cglib.Mock;

import org.jmock.cglib.MockObjectTestCase;

 

    这是个相当体贴的设计,保证了接口的一致性。对于一套API来说,同样的类却有不同的使用方法是个噩梦。

    easyMock,需要新增加一个import。并且修改一些声明的地方。   

原来

import org.easymock.MockControl;

增加

import org.easymock.classextension.MockClassControl;

 

 

// mock控制器

MockControl control = MockClassControl.createControl(TheClassToMock.class);

 

其他部分不需要变化。虽然这有些变化,但是变化带来了其他的好处,就是:能够支持带有构造参数的具体类,而jMock不支持。这对于大量使用了PicoContainer的代码来说不啻是一个福音。

结论

 

    5 如果需要构造参数,只能使用easyMock

    6 如果喜欢用相同的API操作并且不在乎构造参数,请用jMock

    7 如果愿意等待下一版本的jMock提供构造参数支持,请用jMock

 

参考比较表:

 

EasyMock

jMock

通过接口模拟

控制方法有效次数

定制参数匹配

不需要状态转换

具体类模拟

具体类可有构造参数

接口统一

条件代码在一行中完成

支持其他参数规则,如not

自验证 verify()

综上,我选择了jMock。不过想想看,easyMock3个类实现了大多数常用功能,很不简单啊。而jMock,如果能够提供对Constructor injection的支持就完美了。遗憾。不过从设计上看,jMock里的模式使用堪称典范,很好看哦。

本人对easyMock使用经验不多,如有谬误请指出。

下载地址:

http://www.jmock.org

http://www.easymock.org

比较代码:

http://icecloud.51.net/data/mockobjects.zip

需要:

JUnit3.8.1Cglib2jMock1.0EasyMock1.1

   


版权声明:

本文由冰云完成,作者保留中文版权。
未经许可,不得使用于任何商业用途。
欢迎转载,但请保持文章及版权声明完整。
如需联络请发邮件:
icecloud(AT)sina.com
Blog:http://icecloud.51.net
 

 

 

EasyMock与JMock的比较

MockObjects的选择:EasyMock与JMock的比较 本文假设读者已经了解了MockObjects的使用目的和基本方式,不对MockTest之类的技术作过多解释。仅提醒一句:“不要测试你...
  • m13666368773
  • m13666368773
  • 2011年11月30日 10:48
  • 3635

MockObjects的选择:EasyMock与JMock的比较

MockObjects的选择:EasyMock与JMock的比较本文假设读者已经了解了MockObjects的使用目的和基本方式,不对MockTest之类的技术作过多解释。仅提醒一句:“不要测试你...
  • techcrunch
  • techcrunch
  • 2008年04月09日 00:29
  • 171

mockito框架比jmock好用多了!!

Sorry iteye有问题吧 我一提交怎么产生两个帖子了,不好意思啊!     引述:程序测试对保障应用程序正确性而言,其重要性怎么样强调都不为过。JUnit是必须事先掌握的测试框架,大多数测试框架...
  • legend_x
  • legend_x
  • 2013年12月25日 14:45
  • 1073

Mock-jmock&easymock 小凯总结

目录 一、mock和stub 2 (一)相同点: 2 (二)不同点: 2 二、Easy-Mock与JMock介绍 3 (一)原理与模型: 3 (二)Easy-Mock的简单语法介绍 3 ...
  • m13666368773
  • m13666368773
  • 2011年12月16日 09:24
  • 4221

单元测试及框架简介 --junit、jmock、mockito、powermock的简单使用

一、单元测试 单元测试概念: 所谓MT(MK23),又称为模块测试,是指对软件中的最小可测试单元进行检查和验证。对于面向对象编程,最小单元就是方法。单元测试的目标是隔离程序部件并证明这些单个部件是正确...
  • Luvinahlc
  • Luvinahlc
  • 2013年08月28日 14:33
  • 4835

Java 各种Mock工具比较

转自: http://billben.iteye.com/blog/1872196 http://harrywu304.blog.163.com/blog/static/84566032011...
  • yasi_xi
  • yasi_xi
  • 2014年04月28日 14:56
  • 16272

使用PowerMock和Easymock进行单元测试

Java单元测试对于开发人员质量保证至关重要,尤其当面对一团乱码的遗留代码时,没有高覆盖率的单元测试做保障,没人敢轻易对代码进行重构。然而单元测试的编写也不是一件容易的事情,除非使用TDD方式,否则编...
  • u010860412
  • u010860412
  • 2016年02月16日 20:11
  • 1332

Spring服务层的测试JMock

Spring服务层的测试JMock 研究了2天,终于明白JMock怎么用了。其实原理很简单,模拟测试。 我们在用spring做开发的时候,通常会分N层结构,比如web layer(struts),...
  • m13666368773
  • m13666368773
  • 2011年11月30日 10:59
  • 4249

[置顶]JMock的基本使用方法

JMock是帮助创建mock对象的工具,它基于Java开发,在Java测试与开发环境中有不可比拟的优势,更重要的是,它大大简化了虚拟对象的使用。本文中,通过一个简单的测试用例来说明JMock如何帮助我...
  • m13666368773
  • m13666368773
  • 2011年11月15日 12:04
  • 2480

Maven环境下easymock开发入门实例

在大项目中,都是分模块来完成,比如dao层的数据操作接口没有完成,那么调用它的service层也就无法进行开发和测试了,mock框架就是来解决这个问题的,它只关注业务交互层的操作。 (mock关注的...
  • tianjun2012
  • tianjun2012
  • 2016年01月23日 23:09
  • 658
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MockObjects的选择:EasyMock与JMock的比较
举报原因:
原因补充:

(最多只允许输入30个字)