在这些条件下,伪造一个RGHConnection对象最好的方法是对RGHConnection类应用接口提取。如果你手头一个支持重构的工具,那么它很可能也会支持接口提取方法。我们来看一下接口提取后的情况:

<interface> 
IRGHConnection 
+connect() 
+ disconnect() 
+RFDIReportFor(id:int):RFDIReport 
+ACTIOReportFor(customerID:int) ACTIOReport

  由于retry()和fromPacket()不属于业务相关方法因此只需要在实现类中增加这两个方法,至此我们可以轻松的构建出一个FackeConnection类,并使它能够提供我们所需要的反馈信息,然后将这个伪造的对象用在测试中:

public class FakeConnection implements IRGHConnection 

    public  RFDIReport report; 
    public void connect() {} 
    public void disconnnect(){} 
    public RFDIReport RFDReportFor(int id) {return report;} 
    public ACTIOReport ACTIOReportFor(int customerID) {return null;} 
}

  下面我们来写测试

void testNoSuccess()throws Exception{ 
  CreditMaster master = new CreditMaster("crm2.mas",true); 
  IRGHConnection connection = new FakeConnection(); 
  CreditValidator validator = new CreditValidator(connection,master,"a"); 
  connection.report = new RFDReport(....); 
  Certificate result = validator.validatorCustomer(new Customer(...)); 
  assertEquals(Certificate.VALID,result.getStatus()); 
}

  虽然FakeConnection类看起来有点奇怪:它的方法要么是空的要么就简单的返回null。这种情形并不常见。更糟的是,它有一个任何人都可以看到的并随意设置的公共变量。这样一个类似似乎违反了所有的良好准则。但你要看到,实际上并非如此。对于一个用来使得测试可行的类,规则是所不同的。FakeConnection中的代码并非产品代码。它永远也不属于最终投入运行的应用,而只是为了测试工具和测试而诞生。

  有了这个fake类我们接下去便可以做更多的相关测试。这就是提高代码可测试性和遇到教难构造的的类的时候所采取的一种方法。若代码设计阶段就将RGHConnection设计为接口,那么在后面的测试中会是测试更加方便,使代码在后期的重构也会更加方便。

本文是在读了《Working Effectively with legacy Code 》第九章,关于在无法将类放入测试用具中时遇到的四种最为常见的问题:

  (1)无法轻易创建该类的对象。

  (2)当该类位于测试用具中时,测试用具无法轻易通过编译构建。

  (3)我们需要用到的构造函数具有副作用。

  (4)构造函数中有一些要紧的工作,我们需要感知到它们。

  这四个问题在进行单元测试或者接口测试的时候,会对测试工作造成很大的阻碍,这就是一个代码可测性的问题。当遇到这样的问题的时候,有两种方法,第一、强行构建一个类去完成测试,但是这会造成测试的时候大部分工作都耗费在构建这样一个类的过程中;第二、重构代码,使代码具有可测性。本文将通过书中的列子来简单介绍一下如何提高代码的可测性。

  如在一个计费系统中,我们有一个未测试的Java类:CreditValidator。

public class CreditValidator
       {
             public CreditValidator (RGHConnection connection,
                                             CreditMaster master,
                                             String validatorID) {
       }
     Certificate validateCustomer(Customer customer) throws InvalidaCredit{
      }
     public class RGHConnection
        {
              public RGHConnection(int port, String Name, String passwd) throws IOException {
             }
         }
    }

  我们可以看到CreditValidator构造函数含有三个参数RGHConnection,CreditMaster,validatorID。其中RGHConnection对象在构造时会连接到一个服务器,这个链接被用来从服务器上获取必要的信息,以检查客户的余额。

  宁一个类CreditMaster,则提供一些我们在检查余额的过程中会用到的策略信息。该类的构造函数会从一个文件中加载相关信息,并把这些信息保存在内存中以备后用。

  如果按照我们开头讲的强制构造一个类来完成测试,如下所示:

public void testCreate() throws Exception {
       RGHConnection connection = new RGHConnection(DEFAULT_PORT,"admin","rii8ii9s");
       CreditMaster master = new CreditMaster ("crm2.mas",true);
       CreditValidator validator = new CreditValidator(connection,master,"a");
}

  虽然我们构建一个这个样的类,但是你能忍受这个测试的速度,根据《Working Effectively with legacy Code 》书中提到大于1秒的单元测试,都不叫单元测试。因此在测试中建立到服务器的连接并不是一个好的主意。首先其好事就比较长,况且服务器也并不总是处于服务状态。可想而知RGHConnection是一个令人恼火的参数。我们的设想是:若能创建某种伪造的RGHConnection对象并使CreditValidator相信它是一个真正的RGHConnection的话,就可以避开所有链接的问题了。

  首先来看一下RGHConnection所拥有的方法:

RGHConnection
+ RGHConnection(port,name,password)
+ connect()
+ disconnect()
+RFDIReportFor(id:int):RFDIReport
+ACTIOReportFor(customerID:int) ACTIOReport
+retry()
+fromPacket():RFPacket

  看上去RGHConnection中有一些方法是用来处理与连接相关的任务的:如connect、disconnect以及retry。另外还有一些业务方法。因此如果要伪造一个RGHConnection对象的话,那么这个伪造的对象也必须拥有这些方法也能提供一样的信息。

====================================分割线================================

最新内容请见作者的GitHub页:http://qaseven.github.io/

关于如何提高代码可测试性的一些看法相关推荐

  1. 提高代码质量:如何编写函数

    原文地址:http://luopq.com/2016/02/21/write-good-function/  函数是实现程序功能的最基本单位,每一个程序都是由一个个最基本的函数构成的.写好一个函数是提 ...

  2. Java 性能优化:教你提高代码运行的效率

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:五月的仓颉 cnblogs.com/xrq730/p/486 ...

  3. iar代码优化影响运行速度吗_Java 性能优化:教你提高代码运行的效率

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:五月的仓颉 cnblogs.com/xrq730/p/486 ...

  4. sql缩进提高语句的可读性_为什么要使用列缩进来提高代码的可读性

    sql缩进提高语句的可读性 by Leonardo Carreiro 莱昂纳多·卡雷罗(Leonardo Carreiro) 为什么要使用列缩进来提高代码的可读性 (Why you should us ...

  5. 如何提高代码质量,或者说高质量代码的特征是什么

    高质量代码的三大要素: 可读性.可维护性和可变更性!! 做好代码规范.提高代码质量,能显著增强代码的可读性.可维护性和可变更性.努力提高代码的读写可维护性,是做好代码规范的必要非充分条件.代码规范和架 ...

  6. 程序员如何提高代码能力?

    前言 作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力.众所周知,程序开发的水平提升是一个循序渐进的过程 ...

  7. 如何提高代码可读性、可维护性

    高质量代码的三大要素: 可读性.可维护性和可变更性 做好代码规范.提高代码质量,能显著增强代码的可读性.可维护性和可变更性.努力提高代码的读写可维护性,是做好代码规范的必要非充分条件.代码规范和架构设 ...

  8. OpenCV学习系列教程第五篇:测试和提高代码的效率

    Opencv-Python学习系列教程第五篇 来自opencv-python官方学习文档,本人谨做翻译和注释,以及一些自己的理解 本文由作者翻译并进行代码验证,转载请注明出处~ 官方文档请参阅:htt ...

  9. 阿里程序员工作小技巧:理解CPU分支预测,提高代码效率

    技术传播的价值,不仅仅体现在通过商业化产品和开源项目来缩短我们构建应用的路径,加速业务的上线速率,体现也会在优秀程序员在工作效率提升,产品性能优化和用户体验改善等小技巧方面的分享,以提高我们的工作能力 ...

最新文章

  1. AndroidManifest 配置Activity 一直提示找不到,
  2. 前端神器—Google Chrome Devtools细节详解
  3. 安装漂亮的Faenza1.3与Faience0.5图标主题
  4. ernie和Bert的参数理解
  5. Windows下用VS2015+MSYS编译OpenH264
  6. python中append和insert_python append、extend与insert的区别
  7. SAP MM 顾问在实施项目工作中的苦逼和优势
  8. 百度云无限速下载工具:JDownloader 2 for Mac
  9. Android iTOP-4412全能版 CAN通信集成(完整篇)
  10. 视频教程-Linux C语言编程基础视频精讲-C/C++
  11. 线程----code
  12. [dlang](4)自定义的mysql orm工具
  13. 如何将exe添加到windows本地服务
  14. 我们请来了2017 NIPS大会发文数全球前3的华人教授,讲解网络数据的表征学习(视频+PPT)
  15. PHP脚本定时任务实现及crontab实现定时任务
  16. 关于STM32内部温度传感器的算式话题
  17. 微信公众号开发及运营(一)
  18. swagger升级knife4j:一路上升级打怪
  19. 三层代码讲解--第二课 DATE :2004-05-25
  20. 服务器问题-服务器可以远程登录,本地登录不了

热门文章

  1. Excel 常用快捷键总结(Alt系列)
  2. linux 学习 vi简介; vi下三种工作方式。
  3. mysql 限制单个用户资源_限制MySQL数据库单个用户最大连接数等的方法
  4. 新安装XCode7/XCode8 模拟器无法运行报-unable to boot the simulator解决方法
  5. Hystrix-异常处理
  6. nginx使用用户真实IP做hash(解决经过CND后ip_hash失效问题)
  7. Json string value cannot have line breaks(解决方法)
  8. jQuery:ajax调用成功后返回数据
  9. 如何在VS2013中隐藏引用计数?
  10. 如何使用Bash将stdout和stderr重定向并附加到文件?