My first though was "Should I even need to test those methods?" I invested some time looking for alternatives, but those methods must be private. What could I do?
One option was to modify those methods to be public, anyway this is a hobby project and I know I'm not going to call them from outside. But since the main reason of this project is to learn I though I would best invest the needed time to find the correct solution.
Being a fan of the Java reflection API, I decided to investigate this approach. This is the result:
/**
* Convenient method to execute private methods from other classes.
* @param test Instance of the class we want to test
* @param methodName Name of the method we want to test
* @param params Arguments we want to pass to the method
* @return Object with the result of the executed method
* @throws Exception
*/
private Object invokePrivateMethod (Object test, String methodName, Object params[]) throws Exception {
Object ret = null;
final Method[] methods =
test.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; ++i) {
if (methods[i].getName().equals(methodName)) {
methods[i].setAccessible(true);
ret = methods[i].invoke(test, params);
break;
}
}
return ret;
}
As you can see the code is simply doing the next steps:
- Retrieve an array of declared methods
- Loop the array looking for the method we want to test
- Once found, set the method as public
- Execute the method and return the result
And we want to use it, we only need to do something like:
MyClass instance = new MyClass();
String expResult = "Expected Result";
Object[] params = {"A String Value", "Another Value"};
String result = (String) this.invokePrivateMethod(instance, "myPrivateName", params);
assertEquals(expResult, result);
This is the best I could find. Fair enough but, do you know of a better or more elegant solution?
See you soon.