单元测试的扩展:mock object

    技术2022-05-11  75

    现实问题:     在实际的面向对象软件设计中,我们经常会碰到这样的情况,我们在对现实对象进行构建之后,对象之间是通过一系列的接口来实现。这在面向对象设计里是最自然不过的事情了,但是随着软件测试需求的发展,这会产生一些小问题。举个例子,用户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)