测试开发

《JUnit实战》第6章 使用stub进行粗粒度测试

第6章 使用stub进行粗粒度测试

And yet it moves.

但是它还在转动啊。

——Galileo(伽利略)

本章重点

介绍stub

使用嵌入式服务器代替真正的网络服务器

使用stub单元测试一个HTTP连接

当你开发自己的应用程序时,你可能会发现你想要测试的代码段依赖于其他的类,而它们本身也依赖于另外一些类,这些类则要依赖于开发环境。例如,你可能正在开发一个使用JDBC 访问数据库的应用程序、一个Java EE应用程序(它依赖于Java EE容器提供的安全性、持久性以及其他服务)、一个访问文件系统的应用程序,或者是一个连接到某些使用HTTP、SOAP或其他协议的资源的应用程序。

在前面的章节中,我们已经介绍了JUnit框架。从本章开始,我们将关注使用JUnit来测试一个依赖于外部资源的应用程序。

对于那些依赖于某个特定运行环境的应用程序,编写单元测试是一个挑战。你编写的测试需要具有稳定性,并且在被反复运行时,它们产生的结果必须是一致的。所以,你需要找到一个方法来控制运行测试的环境。一种解决办法是建立真正的需求环境作为测试的一部分,并在其上运行测试。在某些情况下,这种方法是行之有效的,并且可以带来了真正的好处(参见第8章,这一章讨论了容器内测试)。但是,只有在你的开发和构建平台上建立了真实的环境,测试才能充分发挥作用。事实上,这种情况并不总是行得通的。

例如,如果你的应用程序要使用HTTP连接到由第三方提供的一个Web服务器上,但在你的开发环境中通常并不存在那样一个可用的服务器程序,所以,你就需要通过一种方法来模拟服务器,这样你就能够为你的代码编写和运行测试了。

还有另外一种情况,假设你与其他的开发人员正在一起开发一个项目。你想测试项目中你自己负责的那一部分,但其他部分尚未完成,那么你该怎么做呢?一种解决办法是通过使用行为方式相同的仿造系统来替代它,从而模拟缺失的那一部分。

这里有两个策略供我们生成模拟对象:stub技术和使用mock objects。stub是一种原始的方法,但如今仍然很流行,其主要原因是它们允许用户在不修改代码(修改代码是为了使代码具有可测性)的情况下测试代码。mock objects则适用于另一种情况。本章将专门介绍stub技术,而第7章将会详细讨论mock objects。

6.1 stub简介

stub是一种机制,用来模拟真实代码或者尚未完成的代码所产生的行为。stub允许用户测试系统的某一部分,即使其他部分还不可用。通常,stub不会改变你所测试的代码,但是会适当调整代码以提供无缝集成。

DEFINITION stub是一段代码,通常在运行期间使用插入的 stub来代替真实的代码,以便将

其调用者与真正的实现隔离开来。其目的是用一个简单一点的行为替换一个复杂的行为,从而允许独立地测试真实代码的某一部分。

这里有一些可以用到stub 的示例。

当你不能修改一个现有的系统,因为它太复杂,很容易崩溃。

对于粗粒度测试而言,就如同在不同的子系统之间进行集成测试。

stub通常能够在被测系统中提供非常好的可靠性。使用了stub,你就不必修改待测对象,并且你所测试的对象就同将来在产品中要运行的一样。使用stub进行测试通常是在运行环境中完成的,这样就提供了额外的可靠性。

从另一方面来说,stub通常很难编写,尤其当仿真系统非常复杂的时候。stub需要实现与它所替换的代码相同的逻辑,并且要准确地再现复杂的逻辑是非常困难的。因此,这里列出一些使用stub的弊端。

stub往往比较复杂难以编写,并且它们本身还需要调试。

因为stub的复杂性,它们可能很难维护

stub不能很好地运用于细粒度测试。

不同的情况需要不同的stub策略。

一般而言,stub更适合代替代码中的粗粒度部分。你通常会使用stub来代替一个成熟的外部系统,如文件系统、一个到服务器的连接、一个数据库等。使用stub替代对单一类的方法调用是完全可以做到的,但是实现会更加困难(我们会在第7章中详细阐述如何使用mock object做到这一点)。

相关内容

文章评论

表情

共 0 条评论,查看全部
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~