When writing tests, I sometimes access private methods of objects, I made a simple wrapper function because I can't do it by hitting reflection directly every time.
class Main {
/**
*Execute private method of object
*
* @param target Instance of the target object
* @param name method name
* @param <T>Target object type
* @throws Exception Exception at method execution
*/
public static <T> void invokeMethod(T target, String name) throws Exception {
final Method method = target.getClass().getDeclaredMethod(name);
method.setAccessible(true);
method.invoke(target);
}
/**
*Execute private method of object
*
* @param target Instance of the target object
* @param name method name
* @param parameterValues List of arguments
* @param <T>Target object type
* @throws Exception Exception at method execution
*/
public static <T> void invokeMethod(T target, String name, List<?> parameterValues) throws Exception {
//Get an array of argument types
final Class<?>[] parameterTypes = new Class[parameterValues.size()];
parameterValues.stream().map(Object::getClass).collect(Collectors.toList()).toArray(parameterTypes);
final Method method = target.getClass().getDeclaredMethod(name, parameterTypes);
method.setAccessible(true);
method.invoke(target, parameterValues.toArray());
}
/**
*Execute private method of object
*
* @param target Instance of the target object
* @param name method name
* @param parameterValues List of arguments
* @param resultType Class instance of result object
* @param <T>Target object type
* @param <U>Return type
* @return value of return method
* @throws Exception Exception at method execution
*/
public static <T, U> U invokeMethod(T target, String name, List<?> parameterValues, Class<U> resultType) throws Exception {
//Get an array of argument types
final Class<?>[] parameterTypes = new Class[parameterValues.size()];
parameterValues.stream().map(Object::getClass).collect(Collectors.toList()).toArray(parameterTypes);
final Method method = target.getClass().getDeclaredMethod(name, parameterTypes);
method.setAccessible(true);
return resultType.cast(method.invoke(target, parameterValues.toArray()));
}
static class PrivateMethodTest {
private void sayHelloWorld() {
System.out.println(makeHelloMessage("world!"));
}
private void sayHello(String message) {
System.out.println(makeHelloMessage(message));
}
private String makeHelloMessage(String message) {
return "Hello, " + message;
}
}
public static void main(String[] args) throws Exception {
final PrivateMethodTest target = new PrivateMethodTest();
invokeMethod(target, "sayHelloWorld");
final List<Object> params = new ArrayList<>();
params.add("world!");
invokeMethod(target, "sayHello", params);
final String message = invokeMethod(target, "makeHelloMessage", params, String.class);
System.out.println(message);
}
}
Recommended Posts