Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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 http://geekswithblogs.net/geekusconlivus/archive/2006/07/13/85088.aspx

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top