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

时间:2011-02-23 05:42:59

标签: .net unit-testing design-patterns reflection accessor

最近为了实现类的私有方法的单元测试,我使用PrivateObject通过创建私有访问器而不是使用Reflection ,我收到了以下代码审查注释:

  

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

上面的评论让我感到困惑,因为根据我的理解,Reflection也需要object[]来调用任何方法。请帮助我了解最佳方法。

4 个答案:

答案 0 :(得分:6)

  • 您可以使用特殊课程 继承私有类(现在 保护)方法并提供公共 调用不可见的方法 外部受保护的方法。

这在伟大的书重构测试代码http://xunitpatterns.com/

中称为测试特定子类或测试特定扩展

您可以在此处阅读有关测试私有方法的更多详细信息和想法:http://xunitpatterns.com/Test-Specific%20Subclass.html

就像

一样
public TestClass : RealClass
{
    public int  CallHiddenCalculate()
    {
        return  Calculate(); // Calculate is now protected method that we expose for test purposes in this class
    }
}

您可以将此类放置到测试程序集中,这样您的实际程序集就不会包含特定于测试的逻辑和类,因为它的设计很糟糕。

  • 您还可以使用条件编译作为可见性属性,如下所示
    #if DEBUG
        public
    #else
        private
    #endif

在Debug中的这种情况下,您可以调用单元测试,但在发布时,这些方法将不可见。 然而,这种方法比上述方法更糟糕,也更丑陋。

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

至于将私有方法标记为内部并且具有测试程序集,请参阅内部方法有很多原因

  1. 你的前私人方法是可见的 从你的装配原因他们是 内部
  2. 您将拥有测试特定逻辑 (这些方法的内部将 仅用于测试目的) 发布您的产品版本,
  3. 我认为还有更多但最重要的是

答案 1 :(得分:4)

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

如果您真的需要将“私人”成员公开给单元测试,请将它们标记为内部并通过InternalsVisibleTo属性访问它们。这很难看,但它确实有效,你可以稍后通过一些条件编译将它从程序集中删除。

答案 2 :(得分:2)

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

答案 3 :(得分:0)

如果您使用的是 Gallio/MbUnit 测试框架,则可以考虑使用内置的Mirror API。

  

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