确认简化LogAnalyzer测试的方法

"任何面向对象的问题都可以通过添加一个间接层来解决,除非有太多的间接层。"我很喜欢这个观点(引自我的一个朋友),因为单元测试中的很多种"艺术"就是找到一个正确的地方,添加或者使用一个间接层,以此来测试代码。

有些代码无法测试吗?那么添加一个层来封装对这些代码的调用,然后在测试中模拟这个层,或者使这些代码变得可替换(这样其本身就是一个间接层)。当 然,这种艺术也包括避免重复新建一个已经存在的间接层,也包括当这种做法使事情变得过于复杂时,停止使用它。不过,让我们一步步来。

事实上,测试这段代码的唯一途径,是在文件系统中建立一个配置文件。因为我们正尝试着避免这种依赖,所以,我们需要代码不必借助于集成测试也可轻松测试。

回头看看本章开篇提到的宇航员的类比,我们发现,消除这种依赖有一个明确的模式:

1. 找到被测对象所对应的接口或者API。在宇航员的例子中,就是在航天飞机中的操纵杆和控制器,如图3.2所示。

确认简化LogAnalyzer测试的方法 
图3.2  航天飞机模拟器中有真实的操纵
杆和模拟外部世界的屏幕(感谢NASA提供照片)

2. 将接口的底层实现替换为你能控制的东西。它涉及各种各样的飞船监视器、操纵杆和按钮等,将其连接到控制舱,这样,测试工程师就能够控制航天飞机的接口向宇航员显示什么内容。

将这种模式引入代码,还需要以下更多步骤。

1. 找到被测方法所对应的接口。(在这个例子中,"接口"并不是纯粹的面向对象中的概念,是指需要一起协同工作的方法或者类。)在LogAn项目中,是指文件系统配置文件。

2. 如果接口和我们测试的方法直接相关(在这个例子中,我们是直接调用文件系统),则添加一个间接访问层来调用接口,以便能够测试代码。在我们的 例子中,添加间接访问层的方式之一,是将对文件系统的直接调用迁移到一个单独的类(比如FileExtensionManager)。后文将看看其他的方 式。(图3.3显示在这一步骤后系统设计的样子。)

3. 将交互接口的底层实现替换为你能够控制的东西。在我们的例子中,用一个可以控制的桩类(SubExtensionManager)来替换方法所调用的类的实例(FileExtensionManager),以便测试代码可以控制外部依赖。

确认简化LogAnalyzer测试的方法 
图3.3  引入一个间接层来解除对文件系统
的直接依赖。调用文件系统的代码剥离出来,放入
FileExtensionManager类。这个类在我们后
面的测试中将被替换为一个桩类
我们用于替换的实例不会和文件系统打任何交道,这样便解除了对文件系统的依赖。因为我们测试的不是与文件系统交互的类,而是调用该类的代码,所以,如果桩类在运行测试的时候只是给出一些必要的响应而不做任何实际的事情,也没有问题。图3.4显示了这种设计上的变化。
确认简化LogAnalyzer测试的方法 
图3.4  引入一个桩类来打破依赖

图3.4增加了一个新的接口。这个新的接口将使对象模型能够把FileExtensionManager类所做的事情抽象出来,从而允许测试可以新建一个类似于FileExtensionManager的桩对象。这个方法的介绍参见后文。

我们已经见识过在代码中引入可测试性的方式之一--新建一个新的接口。现在让我们来了解代码重构,和在代码中引入接缝的概念。

你可能感兴趣的:(log)