Sooner or later you will run into this issue - you have a class X in some assembly A. Class X is internal to assembly A, but you can read that as “public to the classes from assembly A”. Now, you want to unit test this class but your unit test classes are kept in a separate assembly - let's call the class XTest and the assembly ATest. How do you go about doing this in the cleanest possible way?
Before I give you the solution, note that this is not the case where you're testing internals of the class. You are testing internals of the assembly, and that is not the same thing. You are still testing public methods of a class, it's just that this class is local to the assembly.
The best solution that you can come up on your own is to have a wrapper public class that exposes public interface (note: all “public” methods of the class X will in fact be internal) of the class X and to surround the definition of this class with #if TEST or something similar. Other variations of this like moving the test class XTest into the assembly A are out of the question - you want to keep tests separate from the production code.
Fortunately, there is a better solution if you can use .NET 2.0 - Microsoft has added a new attribute called InternalsVisibleToAttribute so you can tell one assembly to expose internals to another. This should probably be used only for unit testing as I cannot imagine any other usage that would not go against basic design principles.
I'd love to take credit for finding this solution but alas that is not the case - I've found out about this from this blog post. Took me quite a while to find it though as most discussions about this problem end up straying into different issue altogether (whether to test private methods of a class, which is not what this is about as I explained).
This would be a good time to plug TestDriven.net, by far the best unit testing helper app/add-in out there. Go get it if you don't already use it (works even with Express versions of Visual Studio!).
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5