24

我正在尝试对具有许多内部功能的类进行单元测试。这些显然也需要测试,但我的测试项目是独立的,主要是因为它涵盖了许多相关的小型项目。到目前为止,我所拥有的是:

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 可以生成的自动生成测试时,它询问了与向测试项目显示内部结构有关的事情。好吧,现在我正在使用 NUnit 并且非常喜欢它,但是我怎样才能用它实现同样的目标呢?

4

5 回答 5

32

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

这是一个链接,其中包含一些有用的附加信息和演练:

要实际回答您的问题... Internal 和 protected 在 .NET Reflection API 中无法识别。这是来自MSDN的引文:

C# 关键字 protected 和 internal 在 IL 中没有意义,也没有在反射 API 中使用。IL 中对应的术语是 Family 和 Assembly。要使用反射识别内部方法,请使用IsAssembly属性。要识别受保护的内部方法,请使用IsFamilyOrAssembly

于 2008-10-05T01:44:30.940 回答
6

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

例如,将以下内容添加到任何类之外的程序集中:

[assembly: InternalsVisibleTo("AssemblyB")]

或者对于更具体的定位:

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

请注意,如果您的应用程序程序集具有强名称,那么您的测试程序集也需要具有强名称。

于 2008-10-05T01:44:43.483 回答
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

于 2008-10-05T01:47:13.133 回答
6

您的代码仅显示字段 - 所以我希望它不会显示任何内部成员,因为字段应该始终是私有的 IMO。(常量可能是个例外。)

ButtonedForm.TitleButton 实际上有任何非私有字段吗?如果您试图找到内部方法,那么显然您需要调用GetMethods(或GetMembers)来获取它们。

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

于 2008-10-05T06:48:48.423 回答
1

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

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

不过,我想知道,如果您无法访问源代码,您会怎么做?你怎么能进入内部领域?.Net Reflector 可以看到该代码,但我猜它只是在查看 IL。

于 2009-06-03T20:41:40.400 回答