views:

181

answers:

4

I am in the process of writing of writing some unit tests. In particular I want to test some private methods.

So far the I have come up with using.

#define private public

But I am not happy with this as it will destroy all encapsulation from the point of view of the unit test.

What methods do you use to unit-test private methods.

+12  A: 

If the methods are complex enough to warrant testing in isolation, then refactor them into their own class(es) and test via their public interface(s). Then use them privately in the original class.

Mike Seymour
yes, the urge to unit test private methods is usually a design smell.
Felix Ungman
huh? why on earth should public functions warrant more testing than private ones?
Assaf Lavie
I don't understand why wanting to unit test a private method is design smell. Lets say, I start writing a class, and at the same time write the unit-test, before I start writing the public function, I write some fairly simple private functions that I want to prove works before I start to implement the public functions.
David Ashmore
@Assaf: private functions can't be tested unintrusively, so if they need testing in isolation you must either be make them public (where they are, or in another class), or add an intrusive testing mechanism. My suggestion is to refactor so that all code can be tested unintrusively; in my view (which not everyone will share) this also gives a cleaner design, by reducing the responsibilities of the original class, and allowing reuse of what was previously private functionality. Use Anthony's suggestion of a friend test class if you prefer large classes with multiple responsibilities.
Mike Seymour
@David: it's a smell because it indicates that the class has multiple responsibilities (implementing its public interface, and also implementing private functionality). It may be a cleaner design to delegate the private functionality to other classes, rather than to private methods.
Mike Seymour
@Assaf: public functions warrant more testing because they are part of the interface of the class. Private functions aren't. You can test private functions (or other internal components which are not accessible to outsiders, e.g. line 4 of some public function) indirectly via the functions which call them, or you use friends, or you define what they do properly and test that via a public interface. I prefer 1 and 3 over 2, so if something needs direct testing I want it to be public (somewhere). As a direct consequence of that policy, things that aren't public don't need direct testing.
Steve Jessop
If you do extract a class to allow for testing, be sure to think carefully about which methods should be included and how the class should be named. Done correctly, you've now not only made the class easier to test, but have also made it easier to understand for the maintenance engineer who will eventually inherit your code.
Dan Bryant
@Assaf: looking at it another way, I think that tests should not need to be removed if you change the implementation details of the class without changing its public interface (or protected, if you like). You might want to *add* tests after a re-write, when you're white-box testing, to catch new "risky" cases. You shouldn't have to remove them -- the new implementation is supposed to do every significant thing the old one did. But private functions are implementation details. Tests which stop working when an implementation detail changes, even though nothing is actually broken, are nuisances.
Steve Jessop
@David: in your particular case, I'd call that ad-hoc programmer testing. Write the test as part of the class (perhaps a public `test_internals()` function which returns true or false. Perhaps a test class which is a `friend` of your class), or make the functions temporarily public. Test your private functions. Then write your public functions, make sure they pass all their tests. Once they do, you no longer need or want your tests to ensure that your class contains that particular implementation detail, so don't check those tests in.
Steve Jessop
+9  A: 

Rather than the nasty #define hack you mention in the question, a cleaner mechanism is to make the test a friend of the class under test. This allows the test code (and just the test code) access to the privates, whilst protecting them from everything else.

However, it is preferable to test through the public interface. If your class X has a lot of code in the private member functions then it might be worth extracting a new class Y which is used by the implementation of class X. This new class Y can then be tested through its public interface, without exposing its use to the clients of class X.

Anthony Williams
+1  A: 

I don't think unit test cases would be required for private methods.

If a method is private it can used only within that class. If you have tested all the public methods using this private method then there is no need to test this separately since it was used only in those many ways.

aeh
+1  A: 
Manoj R