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