Testing Private Methods
I've been playing with TestNG for a few days now. I really like it. It makes me want to write more tests.
I was wondering if there was a way to create a test for a private method, so I went to the source. I asked Cédric about it. He mentioned that I should use the Reflection API.
The goal was to write a test for the validate method in the following class:
package net.thauvin.erik;
public class Example {
// …
private static int validate(String username, String password, int days) {
// …
return days;
}
}
In order to invoke the validate method in my test, I simply needed to:
- Retrieve the method using
Class.getDeclaredMethod() - Make it accessible using
Method.setAccessible()
as follows:
package net.thauvin.erik;
import org.testng.annotations.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ExampleTest {
// …
@Test
public void validateTest() throws NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
final Method validate = Example.class.getDeclaredMethod("validate",
String.class, String.class, int.class);
validate.setAccessible(true);
assert (new Integer(10).equals(validate.invoke(validate, "test",
"passw0rd", new Integer(10))));
}
}
Pretty nifty trick.
[@514]Bob emailed me the following:
I would just make the method package-private (default access) and put the test in the same package.Bob
As I told him, friendly access doesn't always work for me because of the way I obfuscate private methods. I could make exceptions in my obfuscator settings, but that's a lot more work.
You might want to read Bob's post on Package Scoping and Unit Testing.
[@395]
Eugene rightfully pointed out that Commons Lang provides helpers to reflectively invoke methods.




