Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.NET中对私有方法进行单元测试的最佳实践是什么?_.net_Unit Testing_Design Patterns_Reflection_Accessor - Fatal编程技术网

在.NET中对私有方法进行单元测试的最佳实践是什么?

在.NET中对私有方法进行单元测试的最佳实践是什么?,.net,unit-testing,design-patterns,reflection,accessor,.net,Unit Testing,Design Patterns,Reflection,Accessor,最近,为了实现类的私有方法的单元测试,我使用PrivateObject创建私有访问器,而不是使用反射,我收到了以下代码评审意见: “我对私有对象的主要关注是在构造函数中使用对象[]。它用JavaScript风格的运行时错误检测取代编译器强制执行的强类型。因此,我个人不推荐使用它。” 上面的这个评论让我很困惑,因为根据我的理解,反射还需要对象[]来调用任何方法。请帮助我理解最好的方法是什么。您是对的,使用反射与使用PrivateObject模式有很多相同的缺陷。更好的解决方案是避免专门测试私有方法

最近,为了实现类的私有方法的单元测试,我使用PrivateObject创建私有访问器,而不是使用反射,我收到了以下代码评审意见:

“我对私有对象的主要关注是在构造函数中使用对象[]。它用JavaScript风格的运行时错误检测取代编译器强制执行的强类型。因此,我个人不推荐使用它。”


上面的这个评论让我很困惑,因为根据我的理解,反射还需要
对象[]
来调用任何方法。请帮助我理解最好的方法是什么。

您是对的,使用反射与使用PrivateObject模式有很多相同的缺陷。更好的解决方案是避免专门测试私有方法。

有趣的问题。通常,单元测试旨在从类的使用者的角度验证类的公共行为。也就是说,消费者不在乎你怎么做,只要你的班级信守承诺

如果您确实需要将“private”成员公开给单元测试,请将它们标记为internal,并通过InternalsVisibleTo属性使其可访问。它很难看,但它可以工作,您可以稍后通过一些条件编译将其从程序集中排除。

  • 您可以使用 使用private(现在)继承类 受保护的)方法,并提供公共 从中调用不可见的方法 外部保护方法
这在《重构测试代码》一书中被称为测试特定子类或测试特定扩展

您可以在此处阅读有关测试私有方法的更多详细信息和想法:

它就像

public TestClass : RealClass
{
    public int  CallHiddenCalculate()
    {
        return  Calculate(); // Calculate is now protected method that we expose for test purposes in this class
    }
}
您可以将该类放置到测试程序集,这样您的真实程序集就不会包含特定于测试的逻辑和类,因为它的设计很糟糕

  • 还可以对可见性属性使用条件编译,如下所示
#如果调试 公众的 #否则 私有的 #恩迪夫 在这种情况下,在Debug中可以调用单元测试,但在release中这些方法将不可见。 然而,这种方法比上述方法更糟糕,也更丑陋

仅仅测试公共接口很容易就不够了(通常是不够的),这样就可以说您获得了良好的测试覆盖率,并且您的代码易于维护和重构

至于将私有方法标记为内部方法,并让测试程序集看到内部方法是不好的,原因有很多

  • 您的前私有方法是可见的 因为他们是 内部的
  • 您将拥有特定于测试的逻辑 (这些方法的内部 仅用于测试目的)在 产品的发布版本, 哪个是坏的

  • 和我认为有更多但最重要的是

    如果你使用的是<>>/>>测试框架,你可能会考虑内置的API。

    有时,编写测试最明显的方法是访问非公共状态或行为。这可能不是编写测试的最佳方式,但目前看来似乎是最简单的解决方案。MbUnit提供了几个类来帮助访问非公共成员


    ... 当然,将属性、访问器和方法标记为内部意味着您完全相信另一个开发人员(或您未来的自己)在您的程序集中工作时会遵守使用这些方法的规则=)谢谢您的回复,我无法避免测试私有方法这是一项要求。所以想在反射和私有物体之间做出选择understanding@Chirag-如果已对所有公共方法进行了单元测试,则将对私有方法进行隐式测试。那些没有被单元测试覆盖的私有方法是多余的,应该删除。您测试私有方法的需求可以通过测试公共方法来满足。如果要求在单元测试中显式调用私有方法,那么要求是错误的(我的观点)。@Lieven这通常是错误的方法,私有方法的隐式测试与测试小方法的真实单元测试相比,非常接近使用UI测试程序。假设您有一个类,其中有一个大方法,有5个参数,其中包含20个私有方法,这些私有方法处理公共方法在工作期间创建的各种数据块。如果您只测试这个公共方法,而不测试私有方法,那么您的方法就不是TDD,单元测试也不会显示问题所在,它们只会指出某个地方出了问题。“这是不够的。”瓦伦丁·库祖布,我明白你的意思,但接下来要谈的是你希望测试的水平。我只测试类的接口。如果它们能够工作,这就足够让我对自己的代码有信心,并且能够在不重构任何测试的情况下更改我的私有方法。下面的链接解释说POV非常好,但和所有东西一样,它是在旁观者的眼中。感谢您的回复,我无法避免测试私有方法,因为这是必需的。因此,我想在反射和私有对象之间做出选择,并正确理解+1-我喜欢它!这也可以扩展到受保护的访问者!我今天学到了一个有用的技巧。 #if DEBUG public #else private #endif