mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-10 12:20:09 +08:00
handle array and primary types
This commit is contained in:
parent
fe7420c99a
commit
af3af6b272
@ -3,6 +3,7 @@ package com.alibaba.testable.core.tool;
|
||||
import com.alibaba.testable.core.model.Null;
|
||||
import com.alibaba.testable.core.util.TypeUtil;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -13,39 +14,14 @@ import java.lang.reflect.InvocationTargetException;
|
||||
public class OmniConstructor {
|
||||
|
||||
public static <T> T newInstance(Class<T> clazz) {
|
||||
return newInstance(clazz, isJavaAgentEnabled(clazz));
|
||||
}
|
||||
|
||||
public static <T> void appendInstance(Object target, Class<T> clazz) {
|
||||
return;
|
||||
}
|
||||
|
||||
public static <T> void appendInstance(Object target, int count, Class<T> clazz) {
|
||||
return;
|
||||
}
|
||||
|
||||
private static boolean isJavaAgentEnabled(Class<?> clazz) {
|
||||
try {
|
||||
clazz.getDeclaredConstructor(Null.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static <T> T newInstance(Class<T> clazz, boolean withJavaAgent) {
|
||||
try {
|
||||
Constructor<?> constructor = withJavaAgent ?
|
||||
clazz.getDeclaredConstructor(Null.class) : clazz.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
Object ins = withJavaAgent ? constructor.newInstance(new Null()) : constructor.newInstance();
|
||||
for (Field f : TypeUtil.getAllFields(clazz)) {
|
||||
f.setAccessible(true);
|
||||
if (!f.getType().isPrimitive()) {
|
||||
f.set(ins, newInstance(f.getType(), withJavaAgent));
|
||||
}
|
||||
if (clazz.isPrimitive()) {
|
||||
return newPrimitive(clazz);
|
||||
} else if (clazz.isArray()) {
|
||||
return newArray(clazz);
|
||||
} else {
|
||||
return newObject(clazz);
|
||||
}
|
||||
return (T)ins;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
@ -57,4 +33,87 @@ public class OmniConstructor {
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void appendInstance(Object target, Class<T> clazz) {
|
||||
appendInstance(target, 1, clazz);
|
||||
}
|
||||
|
||||
public static <T> void appendInstance(Object target, int count, Class<T> clazz) {
|
||||
return;
|
||||
}
|
||||
|
||||
private static <T> T newObject(Class<T> clazz)
|
||||
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
Constructor<?> constructor = getBestConstructor(clazz);
|
||||
constructor.setAccessible(true);
|
||||
Object ins = newInstance(constructor);
|
||||
for (Field f : TypeUtil.getAllFields(clazz)) {
|
||||
f.setAccessible(true);
|
||||
f.set(ins, newInstance(f.getType()));
|
||||
}
|
||||
return (T)ins;
|
||||
}
|
||||
|
||||
private static <T> T newArray(Class<T> clazz) {
|
||||
return (T)Array.newInstance(clazz.getComponentType(), 0);
|
||||
}
|
||||
|
||||
private static <T> T newPrimitive(Class<T> clazz) {
|
||||
if (clazz.equals(int.class)) {
|
||||
return (T)Integer.valueOf(0);
|
||||
} else if (clazz.equals(char.class)) {
|
||||
return (T)Character.valueOf((char)0);
|
||||
} else if (clazz.equals(short.class)) {
|
||||
return (T)Short.valueOf((short)0);
|
||||
} else if (clazz.equals(long.class)) {
|
||||
return (T)Long.valueOf(0L);
|
||||
} else if (clazz.equals(double.class)) {
|
||||
return (T)Double.valueOf(0);
|
||||
} else if (clazz.equals(float.class)) {
|
||||
return (T)Float.valueOf(0F);
|
||||
} else if (clazz.equals(byte.class)) {
|
||||
return (T)Byte.valueOf((byte)0);
|
||||
} else if (clazz.equals(boolean.class)) {
|
||||
return (T)Boolean.valueOf(false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isJavaAgentEnabled(Class<?> clazz) {
|
||||
try {
|
||||
clazz.getDeclaredConstructor(Null.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Object newInstance(Constructor<?> constructor)
|
||||
throws InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
Class<?>[] types = constructor.getParameterTypes();
|
||||
if (types.length == 1 && types[0].equals(Null.class)) {
|
||||
return constructor.newInstance(new Null());
|
||||
} else {
|
||||
Object[] args = new Object[types.length];
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
args[i] = newInstance(types[i]);
|
||||
}
|
||||
return constructor.newInstance(args);
|
||||
}
|
||||
}
|
||||
|
||||
private static Constructor<?> getBestConstructor(Class<?> clazz) throws NoSuchMethodException {
|
||||
Constructor<?> bestConstructor = null;
|
||||
int minimalParametersSize = 999;
|
||||
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
||||
Class<?>[] types = constructor.getParameterTypes();
|
||||
if (types.length == 1 && types[0].equals(Null.class)) {
|
||||
return constructor;
|
||||
} else if (types.length < minimalParametersSize) {
|
||||
minimalParametersSize = types.length;
|
||||
bestConstructor = constructor;
|
||||
}
|
||||
}
|
||||
return bestConstructor;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class OmniAccessorTest {
|
||||
DemoParent parent = prepareDemoObject();
|
||||
Object obj = PrivateAccessor.<String>invokeStatic(OmniAccessor.class, "getByPath", parent, "c{DemoChild}/gc{DemoGrandChild}", "c/gc");
|
||||
assertTrue(obj instanceof DemoGrandChild);
|
||||
assertEquals(1, PrivateAccessor.<Integer>get(obj, "i"));
|
||||
assertEquals(0, PrivateAccessor.<Integer>get(obj, "i"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -87,12 +87,7 @@ class OmniAccessorTest {
|
||||
}
|
||||
|
||||
private DemoParent prepareDemoObject() {
|
||||
DemoParent parent = new DemoParent();
|
||||
DemoChild child = new DemoChild();
|
||||
DemoGrandChild grandChild = new DemoGrandChild(1);
|
||||
PrivateAccessor.set(parent, "c", child);
|
||||
PrivateAccessor.set(child, "gc", grandChild);
|
||||
return parent;
|
||||
return OmniConstructor.newInstance(DemoParent.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user