2008-10-05 42 views
24

我想单元测试一个具有许多内部函数的类。这些显然也需要测试,但我的测试项目是分开的,主要是因为它涵盖了许多小型的相关项目。我到目前为止是:通过System.Reflection访问内部成员?

FieldInfo[] _fields = 
    typeof(ButtonedForm.TitleButton).GetFields(
     BindingFlags.NonPublic | BindingFlags.Instance | 
     BindingFlags.DeclaredOnly); 
Console.WriteLine("{0} fields:", _fields.Length); 
foreach (FieldInfo fi in _fields) 
{ 
    Console.WriteLine(fi.Name); 
} 

这很好地吐出所有的私人成员,但仍然不显示内部。我知道这是可能的,因为当我乱搞Visual Studio可以生成的自动生成的测试时,它询问了有关向Test项目显示内部结构的问题。那么,现在我正在使用NUnit并非常喜欢它,但是我怎样才能用它实现相同的功能呢?

回答

32

使用InternalsVisibleTo属性将对程序集内部成员的访问授予单元测试程序集会更合适。

这是通过与一些有用的其他信息的链接和散步:

要真正回答你的问题......内部和保护在.NET反射无法识别API。以下是MSDN的引用:

受保护的C#关键字和internal在IL中没有任何意义,并且在Reflection API中没有使用。 IL中的相应术语是Family和Assembly。要使用反射识别内部方法,请使用IsAssembly属性。要确定受保护的内部方法,请使用IsFamilyOrAssembly

+0

我同意使用InternalsVisibleTo,但感谢您的回答:) – 2008-10-05 02:05:43

+0

没问题,即使在您的特定使用情况下使用不同的方法更合适,也可以有实际的解释。 – 2008-10-05 02:16:39

+2

只是一个参考,链接到这个答案的页面是我的,我的网址已经改变。这就是为什么你可能会得到404。尝试此更新的链接http://jason.whitehorn.ws/2007/11/09/The-Wonders-Of-InternalsVisibleTo.aspx – 2008-11-23 00:57:00

6

InternalsVisibleTo程序集级属性添加到您的主项目中,使用程序集名称测试项目应使内部成员可见。

例如以下内容添加到您的装配任何类外:

[assembly: InternalsVisibleTo("AssemblyB")] 

或为一个更具体的目标:

[assembly:InternalsVisibleTo("AssemblyB, PublicKey=32ab4ba45e0a69a1")] 

请注意,如果您的应用程序组件具有很强的名字,你的测试大会也需要强力命名。

6

我认为你需要问你是否应该为私有方法编写单元测试?如果你为你的公共方法编写单元测试,并使用'合理'的代码覆盖率,你是不是已经在测试任何需要作为结果调用的私有方法?

将测试绑定到私有方法将使测试更脆弱。您应该能够在不破坏任何测试的情况下更改任何私有方法的实现。

参考文献:

http://weblogs.asp.net/tgraham/archive/2003/12/31/46984.aspx http://richardsbraindump.blogspot.com/2008/08/should-i-unit-test-private-methods.html http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 http://geekswithblogs.net/geekusconlivus/archive/2006/07/13/85088.aspx

6

您的代码只显示领域 - 所以我希望它不会显示任何内部成员,田应始终是私人IMO。 (可能的例外是常量。)

ButtonedForm.TitleButton实际上是否有任何非私有字段?如果你试图找到内部方法那么显然你需要拨打GetMethods(或GetMembers)来获得他们。

正如其他人所建议的,InternalsVisibleTo非常方便测试(并且几乎仅用于测试!)。至于你是否应该测试内部方法 - 我当然觉得能够这样做是有用的。我不认为单元测试是专有黑盒测试。通常,当您知道公共功能是通过简单的方式连接几个内部方法来实现的时候,对每种内部方法进行全面测试并对公共方法进行一些“伪集成”测试会更容易。

1

使用InternalsVisible的理由是在我的情况下。我们将源代码购买到图表控件。我们已经找到了需要对该源代码管理进行一些修改并编译我们自己的版本的地方。现在为了确保我们没有破坏任何东西,我需要编写一些需要访问某些内部字段的单元测试。

这是InternalsVisible有意义的完美案例。

我想知道,但是,如果您无法访问源代码,您会怎么做?你怎么能到内部的领域? .net反射器可以看到这个代码,但我想它只是看着IL。