单元测试的扩展:mock object

现实问题:
     在实际的面向对象软件设计中,我们经常会碰到这样的情况,我们在对现实对象进行构建之后,对象之间是通过一系列的接口来实现。这在面向对象设计里是最自然不过的事情了,但是随着软件测试需求的发展,这会产生一些小问题。举个例子,用户A现在拿到一个用户B提供的接口,他根据这个接口实现了自己的需求,但是用户A编译自己的代码后,想简单模拟测试一下,怎么办呢?这点也是很现实的一个问题。我们是否可以针对这个接口来简单实现一个代理类,来测试模拟,期望代码生成自己的结果呢?Mock对象就源于此。

模型:
     现在有两个公司,公司A,B是专门从事中间件开发的,但是两者的侧重点不同。假如公司A是专门从事算法实现的,公司B是专门从事界面设计的。一开始,两个公司都已经约好了一个相同的规范,这个规范是固定下来的(也就是接口),然后两个公司自己独立实现相应的具体内容。过了一段时间后,公司B在开发的过程中,想测试一下界面的显示如何,但是公司A的算法还没有完成,那么他该怎么办呢?这里公司B也知道,他提供一个特别数字进去,接口立刻就会返回一个确认的数字,一些简单的确定性结果是知道的。公司B想进行这些测试的话,他不得不根据这些接口写一些简单的代码来代替,这样进行重复的工作有点麻烦。幸好他们都是使用Java来进行规范约定的,他们了解到有一个easymock的类库支持这方面的测试。


底层相关技术:
     让我们来回忆一下,如果用户使用C++和java的程序的生成,C++在最后的阶段还需要连接才能生成一个整体程序,这在灵活性与java源代码的机制是不能比的(java的各个类是独立的,打包的那些类也是独立的,只有在加载进去才进行连接,这在代码被加载进去的时候,我们还可以执行很多的动作,如插入一些相关的业务需求,这也是AOP的一个焦点,javassit代码库的实现类似于这)。所以用java实现Mock对象是很简单的,这里我就介绍一下easymock来说明一下这些测试。

一个样例:
1)准备知识: 了解JUnit框架,easymock, 下载地址

2)样例测试平台: eclipse3.1(默认需要配有JUnit)

3)说明:使用easymock的好处是, 你不需要添加额外的开发环境,他完全是基于JUnit的,因此在eclipse中测试和JUnit的测试方法一样,编写好相关的代码后, RunAs-> JUnitTest就行了。

4)代码实现:

i 首先是公司AB约定的算法接口
// $Id: Calculator.java 2006-4-22 14:17:46 $
package easymock2.samples;

/**
 * @author Sidney J.Yellow(Sidney.J.Yellow@gmail.com)
 */
public interface Calculator {
    int add(int a,int b);
    int sub(int a,int b);
}

ii公司B现在完成了他的展示界面,里面使用到这个接口的加法运算:
// $Id: Show.java 2006-4-22 14:21:32 $
package easymock2.samples;

/**
 * @author Sidney J.Yellow(Sidney.J.Yellow@gmail.com)
 */
public class Show {
    private Calculator calculator;

    public Calculator getCalculator() {
        return calculator;
    }

    public void setCalculator(Calculator calculator) {
        this.calculator = calculator;
    }
   
    public void show(){
        int a=10,b=12;
        System.out.println("10+12="+calculator.add(a,b));
    }
}


iii 现在公司B想测试一下这个界面是否会打印出22这个结果,他该怎么办呢?他想出了一个办法,就是使用easymock来进行简单的测试:
// $Id: ShowTest.java 2006-4-22 14:24:54 $
package easymock2.samples;

import junit.framework.TestCase;
import static org.easymock.EasyMock.*;

/**
 * @author Sidney J.Yellow(Sidney.J.Yellow@gmail.com)
 */
public class ShowTest extends TestCase {
    private Calculator calculator_mock;
    private Show show;
   
    @Override
    protected void setUp() throws Exception {
        calculator_mock=createMock(Calculator.class); //使用EasyMock创建了一个Mock对象
        show=new Show();
        show.setCalculator(calculator_mock); //使用mock对象
        super.setUp();
    }

    public void testShow(){ //测试show方法
        //在Show当中我们使用了a,b是10,12,我们希望mock对象会返回22
        calculator_mock.add(10,12);
        expectLastCall().andReturn(22); //我们希望公司A提供的算法会返回22
        //注意,我们这里没有提高add的方法的具体实现,我们只是会认为10+12会返回22。
       
        replay(calculator_mock);
        //设置期望值后,我们开始调用公司B的show方法,看是否会出错
        //公司B的show方法里面调用了add方法,提供了参数10和12,控制台会打印出22
        show.show();
       
    }
}

iv 测试成功,控制台输出: 10+12=22

当然,easymock还提供了其他更加多的简单操作,这里只是从mock测试的需求上来介绍一下,详细请参考官方文档。

小结:
使用mock对象,我们在单元测试方面做得更加完善,在一些依赖性很强的相关类中,也可以进行单元测试,最终使软件更加健全。


感谢你的阅读!
对这篇文章有什么疑问的话,请联系作者。作者联系地址: Sidney.J.Yellow@gmail.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值