views:

131

answers:

3

I have seen many crazy methods to get access to private variables when unit testing. The most mind blowing I've seen is #define private public.

However, I've never seen anyone suggest turning off private variables at the compiler level. I had always just assumed that you couldn't. I've complained to many a developer that unit testing would be a lot easier if you could just tell the compiler to back off for this one file.

Then I stumble across the -fno-access-control gcc compiler option. It's so obviously the perfect way to unit test. Your original source files are unmodified, no injected friends just for the unit test, no recompiling with bizarre preprocessor magic. Just flick the 'no access control' switch when compiling your unit tests.

Am I missing something? Is this the unit testing silver bullet I hope it is?

The only disadvantage I see is the gcc specific nature of the technique. However, I assume MSVS has a similar flag.

A: 

Yeap, rather helpful GCC option, but MSVC doesn't have nothing like it.
We use macroses instead:

#define class struct
#define private public
#define protected public

^_^

Rageous
+5  A: 

I would argue that unit tests should not need access to private members.

In general, unit tests are meant to test the interface to your classes, not the internal implementation. That way, changes to the internals will only break the tests if the interface has been compromised.

Have a look at my answer to a similar question, and the ensuing discussion. It is a controversial topic, to be sure, but that's my $0.02.

e.James
+1  A: 

I normally try to use only the public interface of my classes in unit tests. Test Driven Development/Design helps a lot here as the resulting classes tend to enable this style of unit test.

However sometimes you do need to let a unit test access non public members, eg replace the contents of a Singleton with a Fake instance. For this I use package protection in Java and friends in C++.

Some people seem to bend over backwards to avoid friends but they should be used when appropriate and their use doesn't compromise the design. They are also declarative and let other programmers know what you are doing.

iain