桩stub和哑元dummy过去主要用于占位,直到真正的事物准备好---允许在周边代码就位之前就能编译和执行某段代码。在现代开发者测试的上下文中,这些对象具有了更多不同目的。除了允许在某些依赖缺失的情况下编译执行代码以外,崇尚测试的程序员还创建了一系列“仅供测试”的工具,用于隔离被测代码、加速执行测试、使随机行为变得确定、模拟特殊情况,以及使测试能够访问隐藏信息。满足这些目的的各种对象具有相似之处,但又有所区别,我们统称为测试替身(test double)。
那么测试替身有什么好处?有哪些类型?如何使用?
1、测试替身的威力
为了验证一段代码的行为符合你的期望,最好的选择是替换其周围的代码,使你获得对环境的完整控制,从而在其中测试你的代码。你有效的将被测代码与其协作者隔离开,以便进行测试。
这是引入测试替身最根本的原因---将被测代码与周围隔离开。此外还有很多原因。总结来说,有如下原因:隔离被测代码、加速执行测试、使执行变得确定、模拟特殊情况、访问隐藏信息。存在多种类型的测试替身可以实现这些效果,多数效果可以用一种测试替身实现,而有些只存在于某种特定类型。
(1)隔离被测代码
在讨论面向对象编程语言的上下文时,我们的世界包含两种东西:被测代码;与被测代码交互的代码。当我们说要隔离被测代码时,意味着将需要测试的代码与所有其他代码隔离开来。如此,我们不仅使测试更加有针对性和容易理解,还更容易建立测试。
这个例子中,一个是被测代码car,两个是协作者engine和route。如果从car的方法中引用的类来关注高一级的抽象层次,并站在car的角度,我们看到的会是car通过route来获取和访问directions。因此用测试替身替换engine和route,即可将car与所有协作者隔离开。由于用伪实现替换了route,因此完全控制了向car提供的各种directions。
(2)加速执行测试
有时候测试替身的主要作用是,加速执行测试。假如route的初始化要设计加权搜索算法,以便找出汽车car当前位置与目的地之间的最短路径。由于今日街道和高速公路网络的复杂性,计算需要花一点时间。那么反馈环会变长。放置一个测试替身,令它总是返回一个预先计算好的通往终点的途径,这样会避免不必要的等待,使测试运行的更快。
(3)使执行变得确定
测试就是指定行为,并验证行为符合规