mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-02-13 21:31:08 +08:00
implement origin-invoker method
This commit is contained in:
parent
14549040d9
commit
c76ed2d84a
@ -3,6 +3,7 @@ package com.alibaba.testable.core.accessor;
|
||||
import com.alibaba.testable.core.exception.MemberAccessException;
|
||||
import com.alibaba.testable.core.util.TypeUtil;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@ -127,6 +128,20 @@ public class PrivateAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T construct(Class<?> clazz, Object... args) {
|
||||
try {
|
||||
Constructor<?> constructor = TypeUtil.getConstructorByNameAndParameterTypes(clazz.getDeclaredConstructors(),
|
||||
TypeUtil.getClassesFromObjects(args));
|
||||
if (constructor != null) {
|
||||
constructor.setAccessible(true);
|
||||
return (T)constructor.newInstance(args);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new MemberAccessException("Failed to invoke private constructor of \"" + clazz.getSimpleName() + "\"", e);
|
||||
}
|
||||
throw new MemberAccessException("Private static constructor of \"" + clazz.getSimpleName() + "\" not found");
|
||||
}
|
||||
|
||||
public static <T> T invokeStatic(Class<?> clazz, String method, Object... args) {
|
||||
try {
|
||||
Class<?>[] cls = TypeUtil.getClassesFromObjects(args);
|
||||
|
@ -0,0 +1,15 @@
|
||||
package com.alibaba.testable.core.util;
|
||||
|
||||
public class CollectionUtil {
|
||||
|
||||
public static Object[] slice(Object[] args, int pos) {
|
||||
int size = args.length - pos;
|
||||
if (size <= 0) {
|
||||
return new Object[0];
|
||||
}
|
||||
Object[] slicedArgs = new Object[size];
|
||||
System.arraycopy(args, pos, slicedArgs, 0, size);
|
||||
return slicedArgs;
|
||||
}
|
||||
|
||||
}
|
@ -31,19 +31,9 @@ public class InvokeRecordUtil {
|
||||
mockContext.invokeRecord.get(mockMethodName).add(args);
|
||||
LogUtil.verbose(" Mock constructor \"%s\" invoked in %s::%s", mockMethodName, testClass, testCaseName);
|
||||
} else {
|
||||
mockContext.invokeRecord.get(mockMethodName).add(slice(args, 1));
|
||||
mockContext.invokeRecord.get(mockMethodName).add(CollectionUtil.slice(args, 1));
|
||||
LogUtil.verbose(" Mock method \"%s\" invoked in %s::%s\"", mockMethodName, testClass, testCaseName);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object[] slice(Object[] args, int firstIndex) {
|
||||
int size = args.length - firstIndex;
|
||||
if (size <= 0) {
|
||||
return new Object[0];
|
||||
}
|
||||
Object[] slicedArgs = new Object[size];
|
||||
System.arraycopy(args, firstIndex, slicedArgs, 0, size);
|
||||
return slicedArgs;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.alibaba.testable.core.util;
|
||||
|
||||
import com.alibaba.testable.core.accessor.PrivateAccessor;
|
||||
import com.alibaba.testable.core.model.MockContext;
|
||||
|
||||
import java.util.HashSet;
|
||||
@ -40,7 +41,13 @@ public class MockAssociationUtil {
|
||||
}
|
||||
|
||||
public static Object invokeOrigin(Class<?> originClass, String originMethod, Object... args) {
|
||||
return null;
|
||||
if (originMethod.equals("<init>")) {
|
||||
return PrivateAccessor.construct(originClass, args);
|
||||
} else if (args[0] == null) {
|
||||
return PrivateAccessor.invokeStatic(originClass, originMethod, CollectionUtil.slice(args, 1));
|
||||
} else {
|
||||
return PrivateAccessor.invoke(args[0], originMethod, CollectionUtil.slice(args, 1));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAssociatedByInnerMockClass(String testClassName, String mockClassName) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.alibaba.testable.core.util;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
@ -21,6 +22,22 @@ public class TypeUtil {
|
||||
return cs;
|
||||
}
|
||||
|
||||
/**
|
||||
* get constructor by parameter matching
|
||||
* @param availableConstructors available constructors
|
||||
* @param parameterTypes class to look for
|
||||
* @return constructor which match the parameter classes
|
||||
*/
|
||||
public static Constructor<?> getConstructorByNameAndParameterTypes(Constructor<?>[] availableConstructors,
|
||||
Class<?>[] parameterTypes) {
|
||||
for (Constructor<?> c : availableConstructors) {
|
||||
if (typeEquals(c.getParameterTypes(), parameterTypes)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get method by name and parameter matching
|
||||
* @param availableMethods available methods
|
||||
|
@ -5,12 +5,12 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class InvokeRecordUtilTest {
|
||||
class CollectionUtilTest {
|
||||
|
||||
@Test
|
||||
void should_slice_array() {
|
||||
Object[] args = new Object[]{"1", "2", "3"};
|
||||
Object[] slicedArgs = PrivateAccessor.invokeStatic(InvokeRecordUtil.class, "slice", args, 1);
|
||||
Object[] slicedArgs = PrivateAccessor.invokeStatic(CollectionUtil.class, "slice", args, 1);
|
||||
assertEquals(2, slicedArgs.length);
|
||||
assertEquals("2", slicedArgs[0]);
|
||||
assertEquals("3", slicedArgs[1]);
|
Loading…
Reference in New Issue
Block a user