【问题标题】:Where do you put unit tests for private methods?您将私有方法的单元测试放在哪里?
【发布时间】:2011-01-03 07:20:15
【问题描述】:

C# 类中私有函数的单元测试放在哪里?

article in Wikipedia 建议:

  • 将测试与要测试的成员放在同一类中
  • 使用部分类

就个人而言,这两种方法似乎都不合适,我更喜欢将单元测试完全放在单独的项目中。

对此有什么想法吗?

(我知道关于是否应该测试私有方法存在相当多的争论。我想听听双方的争论。)

【问题讨论】:

  • 我认为将测试代码放在生产代码中是个坏主意。
  • 您使用的是哪个测试框架(如果有)?

标签: c# unit-testing tdd encapsulation information-hiding


【解决方案1】:

私有方法不一定需要直接测试。您可以根据使用这些私有方法的公共方法的测试来确定它们的有效性。

但是,您应该注意确保您的公共方法可以轻松地将模拟依赖项注入到您的私有方法中,以方便测试和模拟所有合理的场景。

编辑:至于你的其他测试应该放在哪里,我建议在你的项目中使用一个单独的子目录来处理你的测试。在为 PHP 应用程序编写测试时,我在项目的根目录中有一个 tests 目录,其目录结构与我的实际应用程序目录结构相同。在其中,我为每个真实的班级都有一个测试班。

在发布到生产环境时,不要将测试类与项目的其余部分一起编译(或者对于 PHP 等解释性语言,不要将测试类部署到生产网络服务器)。

【讨论】:

  • 那么你是说私有函数中的代码不应该有任何依赖项不是该类的构造函数或公共方法作为参数接收的吗?
  • 同意使依赖项可注入,能够替换任何依赖项简化了测试。通过构造函数或属性接收它们是标准的,并且适合容器。如果只是为了可测试性,也可以考虑使用内部方法或属性。
  • @jonathanconway:确实。例如,如果私有方法正在使用数据库连接,它应该从成员变量中获取它,或者应该将它作为参数传递。它不应该出去并自己实例化它。如果是这样,您将无法模拟数据库并让它为测试目的做其他事情(可能模拟失败或其他情况)。
  • 依赖的可注入性是一个与是否测试私有方法或放置测试无关的问题。
  • @Jason:我从没说过。我说他应该使用 DI 来促进通过公共方法测试他的私有方法。这是对我的回答的补充,而不是先决条件。
【解决方案2】:

不要对私有方法进行单元测试。单元测试用于测试类的可见(公共和受保护)接口。私有方法是实现细节,没有必要为它们编写单元测试(它们的行为应该由可见方法的测试隐式测试),导致脆弱的测试(因为实现细节可能会改变)并且是重构的障碍。

如果您认为有一个私有方法需要进行单元测试,这是一个很大的提示,也许它应该被分解到另一个类的公共方法中。

C# 类中私有函数的单元测试放在哪里?

无处可去。它们不存在。

一般来说,我的单元测试在不同的项目中。

【讨论】:

  • 这指向了测试的目的:测试说“你的对象工作正常”,它是:“你的对象的公共接口工作正常”。如果事实是您的私有方法的原因是公共方法,那么它们必须仅存在于为公共方法实现某些东西。因此,如果您测试公共方法,那么您正在测试私有方法。测试驱动开发说:如果您想做某事,请编写测试然后实施它。这样你就只对必要的公共程序进行编程。私有方法将遵循相同的策略。
  • 只有构造函数和私有方法的类对单元测试没有用处吗?
  • “我需要测试这个私有方法”的感觉可能表明代码需要重构,私有方法中的功能应该移动到其他类并公开为公共方法。
【解决方案3】:

我个人也喜欢在单独的项目中进行单元测试。 如果要对私有方法进行单元测试,则可以将私有方法设为内部。然后,您可以通过将以下内容添加到 AssemblyInfo.cs 使内部方法对您的单元测试可见以直接调用:

[assembly: InternalsVisibleTo("MyAssembly.UnitTests")]

【讨论】:

    【解决方案4】:

    你应该做对你有用的事;这对我有用:

    我的单元是一个类:这就是我要测试的。不是方法。我正在尝试做面向对象的编程,所以我把注意力放在了对象上。

    如果我发现自己想测试私有方法,我需要重构。我只想直接测试一个私有方法,因为它和测试之间有太多其他代码,而且因为私有方法本身足够复杂,需要测试注意。因此,我通常会提取类以将该私有方法和其他相关成员拉入一个新类。

    我的班级往往非常。它们易于阅读和理解。当然,我的方法也非常小且易于理解。

    过渡到这种工作方式需要我重新思考我对编程的许多假设和习惯。曾经看似激进的事情现在似乎司空见惯。

    【讨论】:

    • +1 提到如果你想测试私有方法,你(可能)需要重构。
    【解决方案5】:

    我同意通常不应测试私有方法,因为您应该只测试公共接口。

    话虽如此,您可能想要测试私有方法是有原因的:

    1. 您正在使用 TDD,并且您必须开发一个复杂的私有方法。可能需要为私有方法创建测试方法,以使您的编写测试-编写代码-测试周期保持在正确的粒度。

    2. 您可能是团队中的一员,其他人可能需要修改私有方法,并且您希望进行测试以确保更改不会产生问题。

    一些解决方案:

    1. 声明一些委托给私有方法的公共方法,并且仅用于测试目的。这些可以作为前缀,例如与 TestFoo1、TestFoo2 等。

    2. 使用内部

    http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.80).aspx

    【讨论】:

      【解决方案6】:

      您的问题标题和第一句话不同。 :)

      我不确定在哪里放置您的测试。这将取决于语言和 C# 不是我熟悉的东西,但我想你的代码的很大一部分是在私有方法中。如果没有经过测试,我会感到不舒服。代码覆盖率会下降很多。

      【讨论】:

        【解决方案7】:

        我们在 Visual Studio 中使用私有访问器来测试私有方法。这意味着测试类可以存在于单独的项目中。

        但是,我们试图真正限制这些数量,因为:

        • 可以独立的私有方法可以作为公共方法在另一个类中被拉出
        • 在类之外不做任何特别有用的事情的私有方法可以通过该类的公共方法进行测试

        【讨论】:

          【解决方案8】:

          绝对是的。无论如何都应该测试私有方法。并且mbunit 单元测试框架可以访问私有成员。

          请参阅此博客: testing private methods

          【讨论】:

            猜你喜欢
            • 2011-03-04
            • 2014-08-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多