【问题标题】:Questions on unit testing of private methods关于私有方法单元测试的问题
【发布时间】:2012-04-07 21:16:03
【问题描述】:

在 MSTest 中,[Shadowing] 属性可帮助您对来自另一个程序集的私有方法进行单元测试。这是相关链接:What is the Shadowing attribute that the VS uses when it generates unit tests?

我的问题是:

  1. 是否应该单独对私有方法进行单元测试?
  2. 将私有方法的访问器更改为internal 只是为了使其可用于其他测试项目/程序集中的单元测试,这是一种好的(?)做法吗? (使用InternalsVisibleTo
  3. 如果私有方法通过调用它们的公共方法间接测试,是否可以称为“单元”测试?

【问题讨论】:

    标签: .net unit-testing nunit mstest


    【解决方案1】:
    1. 不,不应测试私有方法。您的应用程序将仅与公共 API 交互。因此,您应该针对此交互测试您的班级的预期行为。私有方法是内部逻辑实现的一部分。您的类的用户不应该关心它是如何实现的。
    2. 不,不好。往上看。您应该只测试公共 API。
    3. 您应该只测试公共方法。您不关心公共方法是否会调用私有方法,或者直到测试通过。如果测试失败,修复实现。但无论如何都不要测试私有方法。

    更新(如何定义要测试的内容): 理想情况下(在测试优先的方法中)测试是您班级的第一个用户。当您编写测试时,您会尝试想象用户将如何使用您的类。用户不会与私有方法交互(反射是作弊)。因此,作为类的第一个用户,您的测试不应与私有方法交互。

    【讨论】:

    • 上次我检查过,unit 测试不是 是关于测试用户看到的部分。相反,它是关于测试实现的各个部分。
    • 类的用户是指类消费者(另一个类)。绝对不是人类。
    • 但是,如果您只测试公共接口,我不相信您真的是在 unit 测试。它可能依赖于相当数量的(私有)实现,人们希望将其隔离以进行测试
    • 类职责仅由其公共接口描述。考虑没有公共接口的类。你会为那个类写测试吗?
    • 不,我会删除课程。但是,在我看来,如果您只测试公共接口,它似乎是功能测试,而不是单元测试。您正在测试该类是否提供了承诺的功能。单元测试是关于测试该过程中的每个单独步骤,以便如果其中一部分发生故障,您可以确切地知道发生了什么以及在哪里发生了故障。所以在我看来,这意味着(理想情况下)单元测试也应该在(私有)实现细节上进行。但这只是大声思考。我听说过任何一种方式的建议,不确定是否有一个“正确”的答案
    【解决方案2】:

    简要回答您的问题:

    1. 一般来说,他们不应该这样做。大多数情况下,您的私有位将在测试类合约/公共 API 时进行测试。在这不可能的时候,测试私有方法就像其他任何东西一样是单元测试。

    2. 这很常见。虽然更改可见性可能被认为是坏主意,但仅更改为内部可见性并没有那么糟糕。然而,在像 TDD 这样的方法中,测试的需要通常会以不需要像这样的“hacks”的方式驱动你的设计。但就像我说的,它相当普遍——你不应该太担心它,除非它达到荒谬的程度(例如,暴露类的整个私有部分)。

    3. 只要它测试您班级的单个单元(或one logical concept),它就是单元测试。私有方法通常是作为重构公共部分的结果而创建的,大多数情况下,单单元测试将针对这些方法。如果你觉得你的私有方法不再是一个unit,它可能是一个重构调用。

    另外,我建议看看hereherehere

    【讨论】:

      【解决方案3】:

      我更愿意通过公共可用调用来使用所有私有方法。必须有一个路径可以从公共调用中执行每条专用线路,如果不存在,您可以删除该代码。

      使用 internal 而不是 private 可能会导致一团糟,我不会使用这种方法。

      【讨论】:

        【解决方案4】:

        作为一名 Java 开发人员,我愿意。我也不会更改访问级别。我使用反射来访问私有方法。我不必将它授予我的用户,也不必向他们展示我的单元测试。

        这是 Java 的一个肮脏秘密:您总是可以通过反射来规避访问限制。我不知道 C# 和 .NET 是否也是如此,但您可以查看一下。

        【讨论】:

        • 但是,为什么需要直接测试私有方法而不是通过公共方法测试呢?
        • 为什么?有时我真的很想知道该方法的行为方式。我理解“仅通过公共 API 进行测试”的教条,但与所有极端立场一样,我认为存在逻辑例外。
        • 最后,该方法的行为是否以无法通过公共 API 访问的方式表现不佳并不重要。但无论如何,我也明白你的意思。
        • 不,我不同意。这当然很重要,即使公众无法“接触”它。私有方法由我的类实现调用,因此最终它们会影响公众看到的内容。否则写它们有什么意义?测试私有方法可以缩小你的目标,以确保你的实现是正确的。作为开发人员,这始终是我的责任。我不允许教条主义立场阻止我履行义务。如果测试私有方法可以帮助我做到这一点,那么该死的约定。
        猜你喜欢
        • 2014-08-10
        • 1970-01-01
        • 1970-01-01
        • 2013-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多