How do I unit test (using xUnit) a class that has internal private methods, fields or nested classes? Or a function that is made private by having internal linkage (static
in C/C++) or is in a private (anonymous) namespace?
It seems bad to change the access modifier for a method or function just to be able to run a test.
To test legacy code with large and quirky classes, it is often very helpful to be able to test the one private (or public) method I'm writing right now.
I use the junitx.util.PrivateAccessor-package for Java . Lots of helpful one-liners for accessing private methods and private fields.
As many above have suggested, a good way is to test them via your public interfaces.
If you do this, it's a good idea to use a code coverage tool (like Emma) to see if your private methods are in fact being executed from your tests.
Another approach I have used is to change a private method to package private or protected then complement it with the @VisibleForTesting annotation of the Google Guava library.
This will tell anybody using this method to take caution and not access it directly even in a package. Also a test class need not be in same package physically, but in the same package under the test folder.
For example, if a method to be tested is in
src/main/java/mypackage/MyClass.java
then your test call should be placed insrc/test/java/mypackage/MyClassTest.java
. That way, you got access to the test method in your test class.If you're using JUnit, have a look at junit-addons. It has the ability to ignore the Java security model and access private methods and attributes.
I tend not to test private methods. There lies madness. Personally, I believe you should only test your publicly exposed interfaces (and that includes protected and internal methods).
First, I'll throw this question out: Why do your private members need isolated testing? Are they that complex, providing such complicated behaviors as to require testing apart from the public surface? It's unit testing, not 'line-of-code' testing. Don't sweat the small stuff.
If they are that big, big enough that these private members are each a 'unit' large in complexity -- consider refactoring such private members out of this class.
If refactoring is inappropriate or infeasible, can you use the strategy pattern to replace access to these private member functions / member classes when under unit test? Under unit test, the strategy would provide added validation, but in release builds it would be simple passthrough.