Support static methods with ReflectionTestUtils.invokeMethod()
Prior to this commit, the invokeMethod() utility method in ReflectionTestUtils only supported instance methods. This commit brings the invokeMethod() support on par with the getField() support by supporting the invocation of static methods via two new invokeMethod() variants. Closes gh-23504
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -403,14 +403,65 @@ public abstract class ReflectionTestUtils {
|
||||
/**
|
||||
* Invoke the method with the given {@code name} on the supplied target
|
||||
* object with the supplied arguments.
|
||||
* <p>This method traverses the class hierarchy in search of the desired
|
||||
* method. In addition, an attempt will be made to make non-{@code public}
|
||||
* methods <em>accessible</em>, thus allowing one to invoke {@code protected},
|
||||
* {@code private}, and <em>package-private</em> methods.
|
||||
* <p>This method delegates to {@link #invokeMethod(Object, Class, String, Object...)},
|
||||
* supplying {@code null} for the {@code targetClass} argument.
|
||||
* @param target the target object on which to invoke the specified method
|
||||
* @param name the name of the method to invoke
|
||||
* @param args the arguments to provide to the method
|
||||
* @return the invocation result, if any
|
||||
* @see #invokeMethod(Class, String, Object...)
|
||||
* @see #invokeMethod(Object, Class, String, Object...)
|
||||
* @see MethodInvoker
|
||||
* @see ReflectionUtils#makeAccessible(Method)
|
||||
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
||||
* @see ReflectionUtils#handleReflectionException(Exception)
|
||||
*/
|
||||
@Nullable
|
||||
public static <T> T invokeMethod(Object target, String name, Object... args) {
|
||||
Assert.notNull(target, "Target object must not be null");
|
||||
return invokeMethod(target, null, name, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the static method with the given {@code name} on the supplied target
|
||||
* class with the supplied arguments.
|
||||
* <p>This method delegates to {@link #invokeMethod(Object, Class, String, Object...)},
|
||||
* supplying {@code null} for the {@code targetObject} argument.
|
||||
* @param targetClass the target class on which to invoke the specified method
|
||||
* @param name the name of the method to invoke
|
||||
* @param args the arguments to provide to the method
|
||||
* @return the invocation result, if any
|
||||
* @since 5.2
|
||||
* @see #invokeMethod(Object, String, Object...)
|
||||
* @see #invokeMethod(Object, Class, String, Object...)
|
||||
* @see MethodInvoker
|
||||
* @see ReflectionUtils#makeAccessible(Method)
|
||||
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
||||
* @see ReflectionUtils#handleReflectionException(Exception)
|
||||
*/
|
||||
@Nullable
|
||||
public static <T> T invokeMethod(Class<?> targetClass, String name, Object... args) {
|
||||
Assert.notNull(targetClass, "Target class must not be null");
|
||||
return invokeMethod(null, targetClass, name, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the method with the given {@code name} on the provided
|
||||
* {@code targetObject}/{@code targetClass} with the supplied arguments.
|
||||
* <p>This method traverses the class hierarchy in search of the desired
|
||||
* method. In addition, an attempt will be made to make non-{@code public}
|
||||
* methods <em>accessible</em>, thus allowing one to invoke {@code protected},
|
||||
* {@code private}, and <em>package-private</em> methods.
|
||||
* @param targetObject the target object on which to invoke the method; may
|
||||
* be {@code null} if the method is static
|
||||
* @param targetClass the target class on which to invoke the method; may
|
||||
* be {@code null} if the method is an instance method
|
||||
* @param name the name of the method to invoke
|
||||
* @param args the arguments to provide to the method
|
||||
* @return the invocation result, if any
|
||||
* @since 5.2
|
||||
* @see #invokeMethod(Object, String, Object...)
|
||||
* @see #invokeMethod(Class, String, Object...)
|
||||
* @see MethodInvoker
|
||||
* @see ReflectionUtils#makeAccessible(Method)
|
||||
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
||||
@@ -418,20 +469,26 @@ public abstract class ReflectionTestUtils {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public static <T> T invokeMethod(Object target, String name, Object... args) {
|
||||
Assert.notNull(target, "Target object must not be null");
|
||||
public static <T> T invokeMethod(@Nullable Object targetObject, @Nullable Class<?> targetClass, String name,
|
||||
Object... args) {
|
||||
|
||||
Assert.isTrue(targetObject != null || targetClass != null,
|
||||
"Either 'targetObject' or 'targetClass' for the method must be specified");
|
||||
Assert.hasText(name, "Method name must not be empty");
|
||||
|
||||
try {
|
||||
MethodInvoker methodInvoker = new MethodInvoker();
|
||||
methodInvoker.setTargetObject(target);
|
||||
methodInvoker.setTargetObject(targetObject);
|
||||
if (targetClass != null) {
|
||||
methodInvoker.setTargetClass(targetClass);
|
||||
}
|
||||
methodInvoker.setTargetMethod(name);
|
||||
methodInvoker.setArguments(args);
|
||||
methodInvoker.prepare();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Invoking method '%s' on %s with arguments %s", name, safeToString(target),
|
||||
ObjectUtils.nullSafeToString(args)));
|
||||
logger.debug(String.format("Invoking method '%s' on %s or %s with arguments %s", name,
|
||||
safeToString(targetObject), safeToString(targetClass), ObjectUtils.nullSafeToString(args)));
|
||||
}
|
||||
|
||||
return (T) methodInvoker.invoke();
|
||||
@@ -452,4 +509,8 @@ public abstract class ReflectionTestUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static String safeToString(@Nullable Class<?> clazz) {
|
||||
return String.format("target class [%s]", (clazz != null ? clazz.getName() : null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user