Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing internal members via System.Reflection?

Tags:

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?

like image 714
Matthew Scharley Avatar asked Oct 05 '08 01:10

Matthew Scharley


2 Answers

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:

  • The Wonders Of InternalsVisibleTo

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.

like image 163
Eric Schoonover Avatar answered Oct 27 '22 10:10

Eric Schoonover


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.

like image 26
Ash Avatar answered Oct 27 '22 10:10

Ash