从一个类中解除所有依赖的最简单、最快速的方法

11

在处理遗留代码并试图创建测试时,我经常从类或方法中分离出依赖项,以便使用模拟来编写单元测试。依赖关系通常以静态类调用和构造函数中的new关键字创建对象的形式出现。

在大多数情况下,静态调用要么通过包装静态依赖项处理,要么(如果是单例模式(或类似模式))以StaticClass.Current.MethodCall()的形式通过其接口将该依赖项传递给构造函数。

在大多数情况下,构造函数中new关键字的用法只是通过在构造函数中传递该接口来替换。

在类的其他部分中使用new关键字的情况,在大多数情况下同样通过上述方法处理,或者根据需要创建工厂,并在构造函数中传递工厂的接口。

我总是使用Resharper的重构工具来帮助我进行所有这些分解,然而,大多数事情仍然是手动操作(可以自动化),对于一些遗留类和方法来说,这可能是非常繁琐的过程。是否有其他重构插件和/或工具能够帮助我进行此过程?是否有一个“在单击中断开此类的所有依赖项”的重构工具?=)

对我来说,所有这些步骤似乎都是许多开发人员的共同问题,在尝试编写Resharper或CodeRush插件之前,我必须询问一下,因为可能已经有人尝试过了。

添加:

关于下面的答案:即使您不想一次性全部分解(一键总的分解可能会引起更多问题),仍然能够轻松地断开一个方法的依赖关系或1-2个依赖关系将有很大的差别。

此外,重构代码有一定的“尝试并查看发生了什么,以了解所有内容的组合”,即使您不检查该代码,一键式的总体分解也会大有帮助。


除了下面提到的经典著作《与遗留代码有效地工作》,您可能会发现.NET中的棕地应用程序开发很有趣:http://www.manning.com/baley/ - AakashM
2个回答

3
我认为没有任何工具可以自动化地完成这项任务。与遗留代码一起工作意味着 - 如您所知 - 一次只更改少量代码。通常,这些步骤故意很小,以防止出错。通常,您应该首先进行的更改是使该代码可测试的更改。编写测试后,您会以这样的方式更改代码的某个部分,以便修复错误或实现RFC。
因为您应该采取小步骤,我认为使用重构工具让所有依赖关系神奇地消失是很难的。对于遗留系统,您几乎永远不想一次性进行大规模更改,因为破坏(由于缺乏测试而无法发现)的风险太大。然而,这并不意味着在这种情况下重构工具没有用处。相反,它们非常有帮助。
如果您还没有阅读过Michael Feathers的书《与遗留代码有效地工作》,我建议您阅读。它详细描述了一系列模式,帮助您将遗留代码重构为更可测试的系统。
祝好运。

我正准备读那本书!你的回答中有很多真理,所以点个赞!但是,即使您可能不想一次性打破所有内容(一个单击总体突破可能会导致更多问题),仍然可以轻松地打破一个方法的依赖项或1-2个依赖项,这将产生很大的区别。此外,重构代码需要一定的“尝试并查看发生了什么,以了解所有内容如何适合在一起”的措施,单击一次完全突破将在这个过程中提供大量帮助,即使您不检查该代码。 - MatteS
现在已经读完了那本书,我仍然认为这样的工具很有用,尽管我可能不想检查代码。但是,仅仅拥有现有依赖关系的概述就非常有用,无论是每个方法、每个类还是我需要更改并编写测试的任何代码部分。此外,阅读那本书也给了我很多关于如何使用这个工具以可选方式打破依赖关系的想法。 - MatteS
@MatteS:看一下NDepend。它可以让你可视化系统中各部分之间的依赖关系。 - Steven

1

当涉及到静态调用依赖时,您可能想要查看Moles。它能够在运行时进行代码注入,以使用您自己的测试实现来存根任何静态或非虚拟方法调用。这对于测试未使用可测试的依赖注入接口设计的旧代码非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接