Friday, June 8, 2012

Testing Private Methods in Java

I’ve been writing a lot of Java lately, and a lot of tests. We always write tests, right? Alas, no cool record-and-playback stuff like FlexMonkey or FoneMonkey, just plain old JUnit 4 tests with plently of Hamcrest goodness.
Suddenly, I realized that I really needed to test some private methods. So, a quick google for “testing private methods java” brings up a good article by Bill Venners. He lists all possible options to test private methods:
  1. Don’t test private methods
  2. Give the methods package access
  3. Use a nested test class
  4. Use reflection
Basically, the only real one is #4, use reflection. Bill didn’t give me the exact code I needed, so lots of googling later I realized that the world is filled with opinionated people (like me), and boy do they love to talk about #1. I just wanted some code, not a lecture, so I had to write my own code. Here is that code for anyone else that just wants to test private methods.
Imagine you have a class MyClass and it has a private method, myMethod(). Sorta like this:
public class MyClass {
    private String myMethod(String s) {
        return s;
    }
}
Then you could use reflection to invoke the method like this:
MyClass myClass = new MyClass();
Method method = MyClass.class.getDeclaredMethod("myMethod", String.class);
method.setAccessible(true);
String output = (String) method.invoke(myClass, "some input");
The real magic is setAccessible(true) which allows the private method to be called outside the class. And shazam, I can now test all my private methods. I was really hoping JUnit 4 would provide some additional facilities specifically for testing private methods, but not luck.

http://saturnboy.com/2010/11/testing-private-methods-in-java/

No comments:

Post a Comment