NickJ NickJ - 1 month ago 13
Java Question

Junit Test of private mthods

I am attempting to write a utility method to allow easy invocation of private methods in classes under test.
What I have is this:

private Object callPrivateMethod(String methodName, Object subject, Object... parameters) {

try {
Class<?>[] paramTypes = new Class<?>[parameters.length];
for (int index=0; index<parameters.length; index++) {
paramTypes[index] = parameters[index].getClass();
}
Method method = subject.getClass().getDeclaredMethod(methodName, paramTypes);
method.setAccessible(true);
return method.invoke(subject, parameters);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
return null;
}
}


But when I attempt to call it using this code:

List<Session> sessions = new ArrayList<Session>();
// fill the array list
String sessionLines = (String) callPrivateMethod("getSessionsForEmail", emailSender, sessions);


I get this exception:

java.lang.NoSuchMethodException: staffing.server.email.EmailSender.getSessionsForEmail(java.util.ArrayList)


The method signature in EmailSender (class under test) look like this:

private String getSessionsForEmail(List<Session> sessions) {
//do stuff
}


Trying to figure out why reflection can't find the method. It is something to to with List and ArrayList not being exactly the same class? If so, what can I do?

Answer

Your code tries to find a method taking an ArrayList (the concrete class of sessions) as argument. But your method doesn't take an ArrayList as argument. It takes a List as argument.

You'll need to pass the types of the parameters of the method in addition to the values of the parameters.

Or you could refactor the code and either make the method protected or package-protected, or put it in another collaborating class as a public method.