通过 System.Reflection 访问内部成员?

发布于 07-07 20:05 字数 547 浏览 11 评论 0原文

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

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 并且非常喜欢它,但是我怎样才能用它实现同样的目标呢?

I'm trying to Unit Test a class that has many internal functions. These obviously need testing too, but my Tests project is seperate, mainly because it covers many small, related projects. What I have so far is:

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);
}

This spits out all the private members nicely, but still doesn't display internals. I know this is possible, because when I was messing around with the autogenerated tests that Visual Studio can produce, it asked about something to do with displaying internals to the Test project. Well, now I'm using NUnit and really liking it, but how can I achieve the same thing with it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

被翻牌2024-07-14 20:05:43

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

以下是一些有用的附加信息和演练的链接:

要真正回答您的问题...Internal 和 protected 在 .NET Reflection API 中不被识别。 以下是 MSDN 的引用:

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


It would be more appropriate to use the InternalsVisibleTo attribute to grant access to the internal members of the assembly to your unit test assembly.

Here is a link with some helpful additional info and a walk through:

To actually answer your question... Internal and protected are not recognized in the .NET Reflection API. Here is a quotation from MSDN:

The C# keywords protected and internal have no meaning in IL and are not used in the Reflection APIs. The corresponding terms in IL are Family and Assembly. To identify an internal method using Reflection, use the IsAssembly property. To identify a protected internal method, use the IsFamilyOrAssembly.

温柔嚣张2024-07-14 20:05:43

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

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

[assembly: InternalsVisibleTo("AssemblyB")]

或者为了更具体的目标:

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

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

Adding the InternalsVisibleTo assembly level attribute to your main project, with the Assembly name of thre test project should make internal members visible.

For example add the following to your assembly outside any class:

[assembly: InternalsVisibleTo("AssemblyB")]

Or for a more specific targeting:

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

Note, if your application assembly has a strong name, your test assembly will also need to be strongly named.

审判长2024-07-14 20:05:43

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

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

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

Your code is only showing fields - so I'd hope it wouldn't show any internal members, as fields should always be private IMO. (With the potential exception of constants.)

Does ButtonedForm.TitleButton actually have any non-private fields? If you're trying to find internal methods then obviously you need to be calling GetMethods (or GetMembers) to get at them.

As others have suggested, InternalsVisibleTo is very handy for testing (and almost solely for testing!). As for whether you should be testing internal methods - I certainly find it useful to be able to do so. I don't regard unit testing as being exclusively black-box testing. Often when you know that public functionality is implemented using a few internal methods connected in a simple way, it's easier to do thorough testing of each of the internal methods and some "pseudo-integration" tests on the public method.

三生殊途2024-07-14 20:05:43

我想你需要问是否应该为私有方法编写单元测试? 如果您为公共方法编写单元测试,并具有“合理”的代码覆盖率,那么您是否已经测试了需要调用的任何私有方法?

将测试绑定到私有方法将使测试更加脆弱。 您应该能够更改任何私有方法的实现,而不会破坏任何测试。

参考文献:

http://weblogs.asp.net/tgraham/存档/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#测试_11
链接

I think you need to ask whether you should write unit tests for private methods? If you write unit tests for your public methods, with a 'reasonable' code coverage, aren't you already testing any private methods that need to be called as a result?

Tying tests to private methods will make the tests more brittle. You should be able to change the implementation of any private methods without breaking any tests.

Refs:

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
Link

玩心态2024-07-14 20:05:43

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

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

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

A justification for using the InternalsVisible is under my circumstances. We purchase the source code to a Chart Control. We have found where we need to make some modifications to that source control and compile our own version. Now to ensure we did not break anything, there are some unit tests I need to write that need access to some internal fields.

This is a perfect case where the InternalsVisible makes sense.

I was wondering, though, what do you do if you do not have access to the source? How could you get to an internal field? .Net Reflector can see that code, but I guess it is just looking at the IL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文