单元测试之如何破除外部依赖

作者: 桃子妈咪 | 来源:发表于2016-07-27 22:48 被阅读896次

一个外部依赖项是系统中的一个对象,被测试代码与这个对象发生交互,但不能控制这个对象(不能控制这个对象返回值;不能控制这个对象的具体行为;对象还未实现)。常见的依赖包括系统时间、Web服务、文件系统、数据库服务、内存等。如何破除这些外部依赖,如何与他们进行交互测试就是本篇文章讨论的主要内容。

使用Stub破除依赖

Stub可以看做是一个依赖项的 ** 可控制 **的替代物,即伪造的对象。利用Stub,使被测试代码可以得到所有需要的输入,独立地测试了代码逻辑。破除依赖首先需要找到被测试工作单元使用的外部接口,然后把这个接口的底层实现替换成Stub。这里的『替换』就是我们常说的『依赖注入』,下面介绍几种常见的依赖注入方法。

  • 构造函数注入
    使用这种方法,需要给被测试类添加一个新的构造函数(或者给已有的构造函数添加一个新参数),参数传入Stub,然后在被测试类众添加一个局部字段用于保存Stub,供被测试方法使用。
  • 用属性get或set注入
    这里需要为每个要注入的依赖项添加一个属性get和set,然后在被测试代码中需要的地方使用这些依赖。
  • 从工厂类返回给被测试代码依赖项
    首先让被测试的工作单元使用工厂类返回的对象实例,然后测试代码中配置该工厂类,让它返回一个Stub。
  • 伪造工厂类
    实现自定义的工厂类,该自定义的工厂类返回一个Stub,然后把这个伪工厂类赋给被测试的工作单元。
  • 继承被测试类
    继承被测试类,重写其虚工厂方法,使其返回Stub。

使用Mock进行交互测试

在上一篇『单元测试之如何编写优秀的单元测试用例』中,我们了解了工作单元有三种最终结果:返回值、内部状态改变、调用第三方对象。基于值的测试验证了一个函数的返回值;基于状态的测试改变被测试对象的状态,然后验证其可见的状态变化;交互测试则是验证一个对象如何向其他对象发送消息的测试。实际单元测试中,优先考虑基于值、基于状态的测试方法,因为这两种测试可以减少对代码内部细节的假设。

Mock是系统中一个伪造的对象,它可以验证被测试对象是否按照预期的方式调用了这个伪对象。Mock与Stub都是伪对象,但是使用Stub时,Stub只是辅助测试运行,单元测试代码仍然是对工作单元进行断言;使用Mock时,Mock对象会记录所有工作单元与其进行的通讯,单元测试代码是对Mock对象进行断言,用来检验交互。

隔离框架应运而生

前面介绍了Stub和Mock在单元测试中的重要作用,但是如果使用手工的Stub和Mock会出现一些缺陷:

  • 如果类或者接口有很多方法、属性,那么就很难为其编写Stub和Mock对象
  • Mock对象需要记录所有工作单元与其通讯的信息,手工编写工作量大且易出错
  • 难以在其他测试中重用Stub和Mock对象

隔离框架是一套API,使用这套API可以在运行时创建和配置伪对象。下面介绍隔离框架常见功能:

  • 动态生成伪对象(Stub、Mock)
  • 模拟返回值和异常
  • 参数匹配
  • 验证方法调用次数
    使用隔离框架,会让我们得单元测试变得更加轻松,帮助我们编写更加易读、易维护、更可靠的测试代码。

相关文章

  • 单元测试之如何破除外部依赖

    一个外部依赖项是系统中的一个对象,被测试代码与这个对象发生交互,但不能控制这个对象(不能控制这个对象返回值;不能控...

  • 设置Spring单元测试的外部依赖

    单元测试中,有时候也依赖外部的组件,比如Redis-Mock。Spring Boot Test需要在上下文启动之前...

  • 第八章(一)

    8.1 单元测试 单元测试图片.png 测试方法之间不要有依赖关系。 因为我们的单元测试并不是仅仅使用一次。 如何...

  • Mockito入门

    mock使用 mock主要在单元测试的时候用来模拟外部依赖接口的返回,即method stub的作用。 一般而言,...

  • Mockito入门和原理初探

    mock使用 mock主要在单元测试的时候用来模拟外部依赖接口的返回,即method stub的作用。 一般而言,...

  • 单元测试 - MockBean

    为依赖外部组件的代码做单元测试,需要使用Mockito,如果是Spring上下文的话,可以使用MockBean 测...

  • SpringBoot-单元测试

    本文主要介绍如何对SpringBoot进行Service和Controller进行单元测试 Jar依赖 Servi...

  • Jest单元测试mock函数

    在编写单元测试过程中经常遇到需要依赖外部数据的情况,比如异步请求就需要依赖网络,但我们在测试过程中又不允许发起实际...

  • 破除路径依赖

    一个人生活中的可能性,远比ta自身想象的要丰富得多。你有没有想过一个问题,在你已经快要模式化的生活里,其实依然有很...

  • 依赖

    如何克服依赖心理 依赖型人格的依赖行为已成为一种习惯,克服首先必须破除这种不良习惯。 清查一下自己的行为中哪些是习...

网友评论

  • 有心人问道:请教如何伪造,伪造也需要很多时间吧?
    桃子妈咪:@YxrWendao 可以根据语言选择合适的隔离框架,例如Java有JMock,Mockito,PowerMock等,利用隔离框架构造对应的伪造对象即可

本文标题:单元测试之如何破除外部依赖

本文链接:https://www.haomeiwen.com/subject/rstojttx.html