TDD是测试驱动开发(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只使用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。

打桩(mock)是单元测试的重要内容。说难点,谈不上吧,能说出来想到的都不算是难点了。

mock有两种。一种是静态打桩,一种是动态打桩。

静态打桩就是在写测试代码之前根据需要打桩的类生成另外一个类,这个类就是mock object。

动态打桩就是mock object是在测试代码运行的时候才生成的。比较常用的mock工具有EasyMock、Jmock、PowerMock、MockMvc。

先说EasyMock,话说十年前,有天我同事跟我说他搜索easymock,发现百度排名第一的文章是我写的blog。好吧,侧面证明了当时关于这方面的资料是匮乏的。

easymock使用

依赖

代码中mock:

EasyMock设计

  • Mock对象能够模拟其他协同模块的行为,被测试模块通过与Mock对象协作,可以获得一个孤立的测试环境。

  • 使用Mock对象可以模拟在应用用不容易构造(如HttpServletRequest必须在Servlet容器中才能构造出来)和比较复杂的对象(如JDBC中的ResultSet对象),从而使测试顺利进行。

  • Mock对象可以根据享有的接口或类动态生成,不仅能避免额外的编码工作,同时也降低了引入错误的可能。

  • 简单即正义

  • 提供对接口的模拟,能够通过录制、回放、检查三步来完成大体的测试过程。

EasyMock源码解析

Mock对象的创建有两种方式:一种是通过EasyMock类提供的createMock方法创建,另一种是通过EasyMock类的createControl方法得到一个IMocksControl实例,再由这个IMocksControl实例创建Mock实例。

而实际上这两种方法内部实现是一样的。

MocksControl类中包含了两个重要的成员变量,分别是接口IMockBehavior和IMocksControlState的实例。

IMocksBehavior的实现类MocksBehavior是EasyMock的核心类,它保存着一个ExpectedInvocationAndResult对象的一个列表,而ExpectedInvocationAndResult对象中包含着Mock对象方法调用和预期结果的映射。MocksBehavior类提供了addExpected和addActual方法用于添加预期行为和实际调用。

MocksControl类中包含的另一个成员变量是IMocksControlState实例。IMocksControlState拥有两个不同的实现类:RecordState和ReplayState。顾名思义,RecordState是Mock对象在Record状态时的支持类,它提供了invoke方法在Record状态下的实现。他还提供了andReturn、andThrow、times等方法的实现。在ReplayState中,andReturn、andThrow、times等方法的实现都是抛出IllegalStateException,因为在Replay阶段,开发人员不应该再调用这些方法。

当调用MocksControl的createMock方法时,该方法首选会生成一个JavaProxyFactory类的对象。JavaProxyFactory是接口IProxyFactory的实现类,它的主要功能就是通过java.lang.reflect.Proxy对指定的接口创建动态代理实例,也就是开发人员在外部看到的Mock对象。

在创建动态代码的同时,应当提供InvocationHandler的实现类。MockInvocationHandler实现了这个接口,它的invoke方法主要的功能是根据Mock对象状态的不同而分别调用RecordState的invoke实现或是ReplayState的invoke实现。

下面是备受吐槽的手绘时间:

简单再解释一下这张图:

当EasyMock类的createMock方法被调用时,它首先创建一个MocksControl对象,并调用该对象的createMock方法创建一个JavaProxyFactory对象和一个MockInvocationHandler对象。JavaProxyFactory对象将MockInvocationHandler作为参数,通过java.lang.reflect.Proxy类的newProxyInstance静态方法创建一个动态代理。

上面介绍的EasyMock创建的源码解析。可以参考上面的思路再看一下记录Mock对象预期行为的源码,在Replay状态下调用Mock对象的源码。

总结

EasyMock是一个使用简单,源码也非常简单的工具。如果看spring系列源码有困难的同学可以看一下EasyMock的源码,思考一下EasyMock的设计理念和设计模式。

招贤纳士:

  • 新美大基础架构部招聘高级开发/专家。详细信息请点击公众号内“招贤纳士”菜单。

  • 爱奇艺招聘后台开发工程师,有意向请将简历发到BOSS邮箱:275824717@qq.com

静儿的个人公众号:

mock打桩之EasyMock的更多相关文章

  1. mock.js 和easy-mock使用

    mock.js 1.项目中引入mock.js <script src="../static/js/mock.js" type="text/javascript&qu ...

  2. mock打桩测试

    pom依赖: <!-- https://mvnrepository.com/artifact/org.jmockit/jmockit --> <dependency> < ...

  3. 有效使用Mock编写java单元测试

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

  4. Mock方法介绍

    1 现有的单元测试框架单元测试是保证程序正确性的一种有效的测试手段,对于不同的开发语言,通常都能找到相应的单元框架. 借助于这些单测框架的帮助,能够使得我们编写单元测试用例的过程变得便捷而优雅.框架帮 ...

  5. 使用 EasyMock 更轻松地进行测试

    from:http://www.ibm.com/developerworks/cn/java/j-easymock.html 测试驱动开发是软件开发的重要部分.如果代码不进行测试,就是不可靠的.所有代 ...

  6. EasyMock 使用方法与原理剖析

    from:http://www.ibm.com/developerworks/cn/opensource/os-cn-easymock/ Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一 ...

  7. EasyMock 使用方法与原理剖析--转载

    原文地址:http://www.ibm.com/developerworks/cn/opensource/os-cn-easymock/ Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一 ...

  8. [置顶] EasyMock的简单使用

    EasyMock总览 下面,我将讲述如何使用JUnit和EasyMock框架来进行单元测试. 在现实情况下,我们通常是在一些类里使用另外的一些类.在进行真正的测试之前,你可能需要做很多的工作,比喻说安 ...

  9. EasyMock入门

    这是一个JavaProject,有关EasyMock用法详见本文测试用例 首先是用到的实体类User.java package com.jadyer.model; public class User ...

随机推荐

  1. 软件开发顶尖高手的杀手锏SQL语句

                  软件开发顶尖高手的杀手锏SQL语句                                                                     ...

  2. 存储引擎-Bitcast

    Bitcast是一种日志型的基于hash表结构的健值对的存储系统,最早追溯于Riak分布式数据库. 目前,Berkeley DB,Tokyo Cabinet,Innostore都使用了这种存储引擎.使 ...

  3. svn中出现各种感叹号说明

    黄色感叹号(有冲突): --这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许你提交,防止你的提交覆盖了别 ...

  4. Oracle 10g DG 数据文件迁移

    背景:某客户Oracle 10g 的DG由于空间不足,之前将部分数据文件迁移到其他目录,如今原目录扩容成功,要将之前迁移的数据文件再次迁移回来. 环境:Oracle 10.2.0.5 DG 单机 首先 ...

  5. VS2017安装包不占用C盘空间的方法,亲试

    问题:普通VS2017的安装方式,不论是在线安装还是下载的离线安装包,都会在安装过程中将安装包保存在C:\ProgramData\Microsoft\VisualStudio\Packages文件夹下 ...

  6. 二分查找算法的C++和PHP实现

    C++实现方式: #include<iostream> #include<stdlib.h>#include<algorithm> using namespace ...

  7. SharePoint2013 列表栏设置

    在实际项目中,会遇到对列表栏的深度操作,比如设置在新建项目也就是newForm是否可见,是否有默认值,默认标题等等,这类深度操作在页面上是无法配置的,因为需要设置SPFild这个对象,但是用share ...

  8. Python入门、练手、视频资源汇总,拿走别客气!

    摘要:为方便朋友,重新整理汇总,内容包括长期必备.入门教程.练手项目.学习视频. 一.长期必备. 1. StackOverflow,是疑难解答.bug排除必备网站,任何编程问题请第一时间到此网站查找. ...

  9. C#本质论笔记

    第一章 C#概述 1.1 Helo,World 学习一种新语言最好的办法就是动手写程序.        C#编译器创建的.exe程序是一个程序集(Assembly),我们也可以创建能由另一个较大的程序 ...

  10. Django rest framework(6)----序列化

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...