mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-10 20:30:11 +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.model.Null;
|
||||||
import com.alibaba.testable.core.util.TypeUtil;
|
import com.alibaba.testable.core.util.TypeUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@ -13,39 +14,14 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
public class OmniConstructor {
|
public class OmniConstructor {
|
||||||
|
|
||||||
public static <T> T newInstance(Class<T> clazz) {
|
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 {
|
try {
|
||||||
clazz.getDeclaredConstructor(Null.class);
|
if (clazz.isPrimitive()) {
|
||||||
} catch (NoSuchMethodException e) {
|
return newPrimitive(clazz);
|
||||||
return false;
|
} else if (clazz.isArray()) {
|
||||||
|
return newArray(clazz);
|
||||||
|
} else {
|
||||||
|
return newObject(clazz);
|
||||||
}
|
}
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (T)ins;
|
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
return null;
|
return null;
|
||||||
} catch (IllegalAccessException e) {
|
} 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();
|
DemoParent parent = prepareDemoObject();
|
||||||
Object obj = PrivateAccessor.<String>invokeStatic(OmniAccessor.class, "getByPath", parent, "c{DemoChild}/gc{DemoGrandChild}", "c/gc");
|
Object obj = PrivateAccessor.<String>invokeStatic(OmniAccessor.class, "getByPath", parent, "c{DemoChild}/gc{DemoGrandChild}", "c/gc");
|
||||||
assertTrue(obj instanceof DemoGrandChild);
|
assertTrue(obj instanceof DemoGrandChild);
|
||||||
assertEquals(1, PrivateAccessor.<Integer>get(obj, "i"));
|
assertEquals(0, PrivateAccessor.<Integer>get(obj, "i"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -87,12 +87,7 @@ class OmniAccessorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DemoParent prepareDemoObject() {
|
private DemoParent prepareDemoObject() {
|
||||||
DemoParent parent = new DemoParent();
|
return OmniConstructor.newInstance(DemoParent.class);
|
||||||
DemoChild child = new DemoChild();
|
|
||||||
DemoGrandChild grandChild = new DemoGrandChild(1);
|
|
||||||
PrivateAccessor.set(parent, "c", child);
|
|
||||||
PrivateAccessor.set(child, "gc", grandChild);
|
|
||||||
return parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user