【问题标题】:Wanting to test private functions is a bad code smell?想要测试私有函数是一种不好的代码味道?
【发布时间】:2016-04-16 23:58:16
【问题描述】:
当我发现自己想要测试具有小型公共 API 和复杂内部调用结构的类的私有函数时,我似乎最终会从以下两种方法中进行选择:
- 如果类具有不依赖于类的功能'
状态并将为其他潜在客户提供有用的功能
代码然后我应该把它分解成一个服务并测试它是公共的
API。
- 如果类的功能依赖于类的状态和
如果断开会紧密耦合,那么我应该测试它
公共 API 通过传递正确的参数,然后命名
测试,以便它引用我所针对的私有函数。
我觉得直接测试私有函数会让类更不容易重构,测试更脆弱,但是通过公共 API 测试私有函数并仅通过名称和正确的参数值绑定它们也感觉有点粗制滥造。
在这些情况下,如果没有进行正确的 TDD,是否有一套规则可以遵守?我别无选择,因为我正在回想起来编写测试。
【问题讨论】:
标签:
unit-testing
refactoring
【解决方案1】:
您不关心被测试的私有方法。您只关心正在测试的公共 API。对于私有方法,重要的是它如何影响对象的可见行为。
如果您的公共 API 的某些行为被实现为私有方法,那么该测试可能会通过 API 方法的参数“定位”私有方法。这本身并不是一件坏事——它涵盖了公共 API 真实行为的真实测试用例。您可能会在稍后阶段决定重构您的类,以便以其他方式实现相同的行为。重要的是测试封装了公共 API 的行为。
然后,您可能会将私有方法提取到它自己的类中,并且该方法成为新类的公共 API 的一部分。那也很好。您的新类成为旧类的依赖项,然后您可以使用 DI 将触发依赖项行为的复杂性与实际测试用例分离。这也很好,只要新班级有明确的理由存在,而不仅仅是为第一个班级提供服务。
这一切都归结为最适合您正在查看的代码的东西 - 完全捕获原始 API 的行为而不必摆弄模拟依赖项是否有意义?在理想情况下,情况可能总是如此,但随着您的 API 变得更大或更复杂或更高级,这可能会导致其自身的问题。
要记住的重要一点是,您的测试从不测试私有方法。他们总是测试被测系统的可见行为,这可能(也可能不会)通过一个或多个私有方法实现。