【问题标题】:Unit testing private methods seems to make the whole solution easier单元测试私有方法似乎使整个解决方案更容易
【发布时间】:2012-10-14 23:53:01
【问题描述】:

让我们假设有一个实用程序类(没有数据)具有一个复杂的(例如,难以测试的)公共方法。它使用随机数生成,返回大量数据和有趣的东西。但是,如果你在小的私有方法中实现它,每个私有方法都会很容易测试,因此整个事情会更容易测试。从应用的角度来看,只有大的方法需要公开,其他的应该是私有的。然而,测试私有方法会导致更容易测试类。我应该如何解决这个问题?

【问题讨论】:

    标签: unit-testing testing tdd private-methods


    【解决方案1】:

    有时生成随机数、返回大数组和其他有趣的东西意味着单个实用程序类负责不止一件事,这意味着应该有更多的类。单个类(单个方法!)的高复杂性有时是糟糕设计的标志。但从来没有一个单一的黄金法则可以遵循。

    【讨论】:

    • 我已经考虑过重构它,但尽管最终结果确实很复杂,但每个步骤就像取平均值并添加一个随机数一样简单。我想不出有什么办法可以把它带出课堂。
    【解决方案2】:

    您是否应该将您的方法保留为单个黑盒算法,其子部分不可测试,或者尝试将尽可能多的职责外化到单独的类,这取决于具体情况。

    您可能有可能会重复使用的子部分,在这种情况下,最好将它们排除在外。您可能有与其他层或硬件通信的子部分——同样的事情。

    这完全取决于这些小子方法的作用,没有上下文很难判断。

    【讨论】:

      【解决方案3】:

      需要测试私有方法应该是一个警告信号。它不是您庞大而复杂的方法的解决方案。将功能提取到更小的类中是解决方案,考虑到 Single Responsibility Principle (SRP)。 SRP 声明一个类实际上应该只做一件事。

      随机数生成、数组处理和有趣的东西至少是三个独立的事情,应该分开做。

      【讨论】:

        【解决方案4】:

        仅测试类的公共 API 有一个非常有力的论据。它使重构代码变得更加容易,因为除非您更改方法签名,否则单元测试不需要更改,它们会验证您的更改没有破坏任何内容。

        话虽如此,有时测试私有方法是有意义的(尽管这是例外,而不是规则)。一些测试框架(例如 MSTest)允许您为此目的访问私有成员,而其他测试框架(例如 nUnit)则不允许,因为他们认为您不应该这样做(在 .Net 的情况下不需要太多编写你自己的反射类/方法来给你访问权限)。

        如果您决定测试您的私有方法,请确保您也测试完整的公共方法,因为您需要公共测试来验证您以后的重构,如上所述。

        【讨论】:

          【解决方案5】:

          测试私有成员会总是让你的测试变得脆弱。当你测试私有方法时,你的测试依赖于可以而且经常会改变的实现细节。一开始您将它们设为私有的原因是您希望能够在不影响其他软件的情况下更改它们。你猜怎么着:如果你暴露了你的隐私,即使它只是使用反射“黑魔法”,你就是在公开它们,因为你的测试也是你软件的一部分。

          如果您觉得必须测试实现细节,无论是因为您的公共 API 做的太多,还是因为私有方法非常重要,您应该重构您的代码并将您的私有成员提取为 公共类 并测试这些。请记住,因为您的测试也是软件的一部分,所以他们应该能够“正常”访问他们使用的代码。

          如果您坚持这些(并非如此)私有方法不能公开,可能是因为害怕允许外部用户/代码访问它们,您可以通过将它们设置为内部

          来限制对这些类的访问em>(在 C# 中)或 package-private(在 Java 中),并让代码的内部结构对您的测试可见。

          无论哪种方式,听起来您的代码要么不经过测试,要么应该(更多)公开。

          【讨论】:

            猜你喜欢
            • 2014-08-10
            • 1970-01-01
            • 1970-01-01
            • 2013-12-08
            • 1970-01-01
            • 2016-04-27
            • 1970-01-01
            相关资源
            最近更新 更多