【问题标题】:Changing private methods as protected or package private for unit test - good or bad?将私有方法更改为受保护或包私有以进行单元测试 - 好还是坏?
【发布时间】:2016-11-14 05:13:43
【问题描述】:

我正在研究 TDD,最近正在寻找如何正确地对私有方法进行单元测试。 Stack Overflow 中的热门答案是:

  • 使用反射使私有方法可以从外部访问。 1
  • 不要测试私有方法。 (改用公共方法。)1 2 3

根据评论区的分歧,似乎每个人都有自己的规则。然后我发现这个tutorial site 提出了一个相当大胆的方法。

  • 制作private方法protectedpackage private。将测试代码放在同一个包中。

    为可测试性而设计意味着设计您的代码,使其更易于测试。为此,您可能必须打破我们在大学中学到的一些原则,例如封装。

尽管 TDD 的原则是为可测试性设计代码,但为此打破封装对我来说并不合适。这种方法是个好方法吗?

【问题讨论】:

  • 如果我必须选择,我会选择测试覆盖率而不是封装。
  • @Robert 但是既然每个私有方法都迫使我选择,那是不是意味着不再有私有方法了?

标签: unit-testing tdd


【解决方案1】:

我认为正确的答案是:不要测试私有方法。 如果您觉得需要测试私有方法,可能会发生以下两种情况之一:

  • 方法不必是私有的:也许可以通过它所在对象的 API 访问该方法。在这种情况下,将其更改为公共(或其他任何非私有)。另一种选择是将方法的行为放在另一个对象的公共方法中,然后为它构建一些专用测试;
  • 该方法必须是私有的,因此您正在测试一些您不应该测试的东西。您正在尝试编写与您正在测试的对象过于耦合的测试。私有方法在定义上是不稳定的,它们会随着时间的推移而频繁变化。这些更改将破坏所有直接验证私有方法的测试。

【讨论】:

  • 我不会对像 DTO 这样过于琐碎的东西进行单元测试。但是“你正在测试你不应该测试的东西”对我来说有点新鲜。什么样的方法不应该测试?
  • 另一个问题。仍然有足够复杂的私有方法需要测试。我该怎么办?如果可能的话,我的想法是将该方法移至一个新类并将其公开。也许有更好的方法?还是没有解决方法,不应该测试?
  • 我所说的“你正在测试你不应该测试的东西”的意思是你可能不需要对私有方法内部的逻辑进行特定测试。也许你可以测试私有方法通过为使用私有方法的代码的公共方法创建测试来编写代码。通过这种方式,您正在有效地测试对象的公共行为,您正在测试作为公共 API 一部分的某些方法,因此,根据定义,它必须是稳定的。但因此,您也在测试需要执行以满足上述“公共行为”的私有代码。
  • 正如我在答案中所写的,私有方法可以移动到它自己的对象中,并且可以变成公共的。或者,您可以通过测试使用该逻辑的另一个公共方法来测试私有逻辑。不要将单元测试视为每个方法的测试,而是尝试从行为方面考虑测试。您的测试应该验证某个对象的行为(对象能够做什么,通过公共 API 可以满足哪些任务),而无需了解该对象如何实现这些行为。
  • 我认为 Ian Cooper 的以下视频可以帮助您更好地理解如何解决这个测试问题以及如何避免编写与被测代码过于耦合的测试:vimeo.com/68375232
【解决方案2】:

如果您可以将 Guava 库添加为依赖项,则可以创建方法 package private 并使用 VisibleForTesting 注释对其进行标记。

我假设您使用的是 Java,尽管您没有明确说明。

【讨论】:

    猜你喜欢
    • 2015-02-26
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2011-07-09
    • 1970-01-01
    • 2011-10-27
    相关资源
    最近更新 更多