Sunday, March 27, 2005

Accessing Private Members in C#

I recently created a class that needed internal visibility; however, I wanted to unit test the methods of the class. I always put my tests in a separate library and couldn't access my class to test it. This brought me to the question, how do you limit the visibility of your classes (or methods etc) in release code, but still make it visible enough to test?

I knew I could use reflection; however, I was looking for a simpler example. I've never gone down the reflection road for unit testing, but it sounds more complicated than necessary. I decided to use conditional compilation like so:

#if TESTING
public
#else
internal
#endif

Obviously, I changed my NAnt build file to define the conditional compilation symbol TESTING, compile, run NUnit, and recompile without the TESTING symbol.

This worked, but made my method signatures ugly:

#if TESTING
public
#else
internal
#endif
void Foo()

So, I threw a #region into the mix and they now look like this

TESTING?public:internal
void Foo()

I heard another idea at ThoughtWorks. You could create a properly visible interface that you ask developers to code to. Then make your actual classes more visible to allow testing. This works also, but still increases complexity in my opinion. Also, I like to use NDoc to generate my documentation and it will document all my public classes that I'd probably like hidden. Sure, I can explicitly exclude things from NDoc, but that seems like a lot of work. Conditional compilation will give me correct visibility with the only sacrifice being my signature split to 2 lines.
Post a Comment