MockObjects的选择:EasyMock与JMock的比较

2024-01-18 00:08

本文主要是介绍MockObjects的选择:EasyMock与JMock的比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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
 


 

 




这篇关于MockObjects的选择:EasyMock与JMock的比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/617590

相关文章

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

如何选择适合孤独症兄妹的学校?

在探索适合孤独症儿童教育的道路上,每一位家长都面临着前所未有的挑战与抉择。当这份责任落在拥有孤独症兄妹的家庭肩上时,选择一所能够同时满足两个孩子特殊需求的学校,更显得尤为关键。本文将探讨如何为这样的家庭做出明智的选择,并介绍星贝育园自闭症儿童寄宿制学校作为一个值得考虑的选项。 理解孤独症儿童的独特性 孤独症,这一复杂的神经发育障碍,影响着儿童的社交互动、沟通能力以及行为模式。对于拥有孤独症兄

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

如何选择SDR无线图传方案

在开源软件定义无线电(SDR)领域,有几个项目提供了无线图传的解决方案。以下是一些开源SDR无线图传方案: 1. **OpenHD**:这是一个远程高清数字图像传输的开源解决方案,它使用SDR技术来实现高清视频的无线传输。OpenHD项目提供了一个完整的工具链,包括发射器和接收器的硬件设计以及相应的软件。 2. **USRP(Universal Software Radio Periphera

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

关键字synchronized、volatile的比较

关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。随着JDK新版本的发布,synchronized关键字的执行效率上得到很大提升,在开发中使用synchronized关键字的比率还是比较大的。多线程访问volatile不会发生阻塞,而synchronize

为什么现在很多人愿意选择做债务重组?债重组真的就这么好吗?

债务重组,起初作为面向优质企业客户的定制化大额融资策略,以其高效周期著称,一个月便显成效。然而,随着时代的车轮滚滚向前,它已悄然转变为负债累累、深陷网贷泥潭者的救赎之道。在此路径下,个人可先借助专业机构暂代月供,经一段时间养护征信之后,转向银行获取低成本贷款,用以替换高昂网贷,实现利息减负与成本优化的双重目标。 尽管债务重组的代价不菲,远超传统贷款成本,但其吸引力依旧强劲,背后逻辑深刻。其一

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符