jmock 与 easymock

MockObjects的选择:EasyMock与JMock的比较

本文假设读者已经了解了MockObjects的使用目的和基本方式,不对MockTest之类的技术作过多解释。仅提醒一句:“不要测试你的MockObjects”。
本文作为一个评测结果的同时,也可以作为EasyMock和jMock的简短教程。他们本身都很易用,可惜带的示例过于复杂,都用了过多的模式。看过本文的例子,相信就可以从容的在项目中使用了。
Java中常用的MockObjects有EasyMock和jMock等。其中EasyMock开发较早,已经出了1.1版本,而jMock前几天才刚推出了1.0 final。作为刚成熟的小弟弟,jMock有什么竞争实力呢?
本比较针对于以下几个方面,代码请见附件。
1 是否能够对具体类进行模拟(当然,对接口模拟是基本功能)
2 是否能够对方法名,参数,返回值进行动态控制
3 基本代码行数
4 是否能够对具有构造参数的具体类模拟
    现在比较开始了。首先制作若干测试文件,很简单。要模拟的有一个接口和一个具体类,叫做TheInterfaceToMock和TheClassToMock,另外,提供方法SampleReturn sampleMethod(Parameter p);以及同名无参数方法。
    第一个测试是针对TheInterfaceToMock,提供ParameterImpl和SampleReturnImpl作为期待的参数和返回值。
    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行。其主要原因,就是easyMcok的Mock机制是基于状态,首先是录制状态,记录下来待测的方法和参数,返回值等,然后切换为回复状态。而jMock没有切换这一步,直接将参数返回值用一句话写出来。确实是一句话:期待一次,方法sampleMethod,参数等于p(equals),将返回sr。其中的一些辅助函数,例如returnValue,eq等等,位于父类MockTestCase。
    结论:
1 如果不能提供MockTestCase作为父类,请使用EasyMock
2 如果需要批量或动态生成测试,请使用更规则的jMock
3 如果喜欢看起来行数少一些,请用jMock
4 如果对状态切换看不顺眼,请用Mock

你可能感兴趣的:(easymock)