【发布时间】:2009-01-08 20:13:43
【问题描述】:
许多开发人员认为测试私有方法是个坏主意。但是,我发现的所有示例都是基于私有方法是私有的,因为调用它们可能会破坏内部对象的状态。但这不仅仅是隐藏方法的原因。
让我们考虑外观模式。我的班级用户需要 2 个公共方法。它们太大了。在我的示例中,他们需要从数据库的 BLOB 中加载一些复杂的结构,对其进行解析,填充一些临时 COM 对象,运行用户宏来验证和修改这些对象,并将修改后的对象序列化为 XML。单个方法的功能相当大:-) 这两种公共方法都需要大多数这些操作。因此,我创建了大约 10 个私有方法,并且有 2 个公共方法调用它们。实际上,我的私有方法不一定是私有的;他们不会破坏实例的内部状态。但是,当我不习惯测试私有方法时,我有以下问题:
- 发布它们对用户来说意味着复杂性(他们有一个不需要的选择)
- 我无法想象这样一个大型公共方法的 TDD 风格,当您编写 500 多行代码只是为了返回一些东西(甚至不是真正的结果)。
- 这些方法的数据是从数据库中检索的,测试与 DB 相关的功能要困难得多。
当我测试私有方法时:
- 我不会发布会让用户感到困惑的细节。公共接口包括 2 个方法。
- 我可以以 TDD 风格工作(逐步编写小方法)。
- 我可以使用测试数据覆盖大部分课程的功能,而无需连接数据库。
谁能描述一下,我做错了什么?我应该使用什么设计来获得相同的奖金并且不测试私有方法?
更新:在我看来,我已经将我所能做的一切都提取到了另一个类中。所以,我无法想象我还能提取什么。从数据库加载由 ORM 层执行,解析流,序列化为 XML,运行宏 - 一切都由独立类完成。此类包含相当复杂的数据结构、搜索和转换例程,并调用所有提到的实用程序。所以,我不认为可以提取其他东西。否则,它的职责(有关数据结构的知识)将在各个类之间进行划分。
所以,我现在看到的最好的解决方法是分成 2 个对象(外观本身和真实对象,私有方法变为公共)并将真实对象移动到没人会试图找到它的地方。在我的情况下(Delphi),它将是一个独立的单元,在其他语言中它可能是一个单独的名称空间。其他类似的选项是 2 个接口,感谢您的想法。
【问题讨论】:
-
似乎已经有一个与此相同的问题:stackoverflow.com/questions/250692/…
-
这是关于在 C# 中测试私有方法的博客coolaspdotnetcode.com/Web/…
-
外观不是一个实现,因此您对外观的测试不应该测试外观运行的所有实现是否有效。如果有的话,您可以通过外观运行一些系统/集成测试,但您的单元应该单独测试。然后你可以测试这些东西是否被正确地粘合在一起(例如,可以在不爆炸的情况下运行),但是当你处理更高级别的抽象时不要担心这些小事情。
标签: unit-testing tdd