mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-25 20:00:17 +08:00
remove n.e class and testable setup method
This commit is contained in:
parent
9321980a68
commit
f614690016
@ -10,7 +10,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* @author flin
|
* @author flin
|
||||||
*/
|
*/
|
||||||
abstract public class ClassHandler implements Opcodes {
|
abstract public class BaseClassHandler implements Opcodes {
|
||||||
|
|
||||||
public byte[] getBytes(String className) throws IOException {
|
public byte[] getBytes(String className) throws IOException {
|
||||||
ClassReader cr = new ClassReader(className);
|
ClassReader cr = new ClassReader(className);
|
@ -4,20 +4,17 @@ import com.alibaba.testable.agent.constant.ConstPool;
|
|||||||
import com.alibaba.testable.agent.model.MethodInfo;
|
import com.alibaba.testable.agent.model.MethodInfo;
|
||||||
import com.alibaba.testable.agent.util.ClassUtil;
|
import com.alibaba.testable.agent.util.ClassUtil;
|
||||||
import com.alibaba.testable.agent.util.CollectionUtil;
|
import com.alibaba.testable.agent.util.CollectionUtil;
|
||||||
import com.alibaba.testable.agent.util.StringUtil;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.tree.*;
|
import org.objectweb.asm.tree.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author flin
|
* @author flin
|
||||||
*/
|
*/
|
||||||
public class SourceClassHandler extends ClassHandler {
|
public class SourceClassHandler extends BaseClassHandler {
|
||||||
|
|
||||||
private static final String CONSTRUCTOR = "<init>";
|
private static final String CONSTRUCTOR = "<init>";
|
||||||
private final List<MethodInfo> injectMethods;
|
private final List<MethodInfo> injectMethods;
|
||||||
|
@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author flin
|
* @author flin
|
||||||
*/
|
*/
|
||||||
public class TestClassHandler extends ClassHandler {
|
public class TestClassHandler extends BaseClassHandler {
|
||||||
|
|
||||||
private static final List<String> TEST_ANNOTATIONS = new ArrayList<String>();
|
private static final List<String> TEST_ANNOTATIONS = new ArrayList<String>();
|
||||||
|
|
||||||
|
@ -5,16 +5,8 @@ package com.alibaba.testable.core.constant;
|
|||||||
*/
|
*/
|
||||||
public final class ConstPool {
|
public final class ConstPool {
|
||||||
|
|
||||||
public static final String TYPE_UTIL = "com.alibaba.testable.core.util.TypeUtil";
|
|
||||||
public static final String CLASS_SUBSTITUTION = TYPE_UTIL + ".TestableSubstitution";
|
|
||||||
public static final String METHOD_ADD_TO_CON_POLL = TYPE_UTIL + ".addToConstructorPool";
|
|
||||||
public static final String METHOD_ADD_TO_MEM_POOL = TYPE_UTIL + ".addToMemberMethodPool";
|
|
||||||
public static final String CLASS_OF_TYPE = "class";
|
|
||||||
public static final String TYPE_CLASS = "Class";
|
|
||||||
public static final String REF_THIS = "this";
|
|
||||||
public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor";
|
public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor";
|
||||||
public static final String ANNOTATION_TESTABLE_INJECT = "com.alibaba.testable.core.annotation.TestableInject";
|
public static final String ANNOTATION_TESTABLE_INJECT = "com.alibaba.testable.core.annotation.TestableInject";
|
||||||
public static final String TESTABLE_SETUP_METHOD_NAME = "testableSetup";
|
|
||||||
public static final String TESTABLE_REF_FIELD_NAME = "_testableInternalRef";
|
public static final String TESTABLE_REF_FIELD_NAME = "_testableInternalRef";
|
||||||
public static final String TEST_POSTFIX = "Test";
|
public static final String TEST_POSTFIX = "Test";
|
||||||
|
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
package com.alibaba.testable.core.generator;
|
|
||||||
|
|
||||||
import com.alibaba.testable.core.model.TestableContext;
|
|
||||||
import com.alibaba.testable.core.constant.ConstPool;
|
|
||||||
import com.sun.tools.javac.code.Type;
|
|
||||||
import com.sun.tools.javac.tree.JCTree.*;
|
|
||||||
import com.sun.tools.javac.util.List;
|
|
||||||
import com.sun.tools.javac.util.ListBuffer;
|
|
||||||
import com.sun.tools.javac.util.Name;
|
|
||||||
import com.sun.tools.javac.util.Pair;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate test class setup method definition
|
|
||||||
*
|
|
||||||
* @author flin
|
|
||||||
*/
|
|
||||||
public class TestSetupMethodGenerator extends BaseGenerator {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MethodName -> (ResultType -> ParameterTypes)
|
|
||||||
*/
|
|
||||||
public ListBuffer<Pair<Name, Pair<JCExpression, List<JCExpression>>>> injectMethods = new ListBuffer<>();
|
|
||||||
public final ListBuffer<Method> memberMethods = new ListBuffer<>();
|
|
||||||
|
|
||||||
public TestSetupMethodGenerator(TestableContext cx) {
|
|
||||||
super(cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JCMethodDecl fetch() {
|
|
||||||
JCModifiers mods = cx.treeMaker.Modifiers(Modifier.PUBLIC);
|
|
||||||
return cx.treeMaker.MethodDef(mods, cx.names.fromString(ConstPool.TESTABLE_SETUP_METHOD_NAME),
|
|
||||||
cx.treeMaker.Type(new Type.JCVoidType()), List.<JCTypeParameter>nil(),
|
|
||||||
List.<JCVariableDecl>nil(), List.<JCExpression>nil(), testableSetupBlock(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JCBlock testableSetupBlock() {
|
|
||||||
ListBuffer<JCStatement> statements = new ListBuffer<>();
|
|
||||||
for (Pair<Name, Pair<JCExpression, List<JCExpression>>> m : injectMethods.toList()) {
|
|
||||||
if (isMemberMethod(m)) {
|
|
||||||
statements.append(addToPoolStatement(m, ConstPool.METHOD_ADD_TO_MEM_POOL));
|
|
||||||
} else {
|
|
||||||
statements.append(addToPoolStatement(m, ConstPool.METHOD_ADD_TO_CON_POLL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cx.treeMaker.Block(0, statements.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMemberMethod(Pair<Name, Pair<JCExpression, List<JCExpression>>> m) {
|
|
||||||
for (Method method : memberMethods) {
|
|
||||||
if (method.getName().equals(m.fst.toString()) && parameterEquals(m.snd.snd, method.getParameterTypes())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean parameterEquals(List<JCExpression> injectMethodArgs, Class<?>[] memberMethodArgs) {
|
|
||||||
if (injectMethodArgs.length() != memberMethodArgs.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < injectMethodArgs.length(); i++) {
|
|
||||||
if (!memberMethodArgs[i].getName().equals(((JCFieldAccess)injectMethodArgs.get(i)).selected.type
|
|
||||||
.toString())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JCStatement addToPoolStatement(Pair<Name, Pair<JCExpression, List<JCExpression>>> m, String addPoolMethod) {
|
|
||||||
JCExpression pool = nameToExpression(ConstPool.CLASS_SUBSTITUTION);
|
|
||||||
JCExpression classType = m.snd.fst;
|
|
||||||
JCExpression methodName = cx.treeMaker.Literal(m.fst.toString());
|
|
||||||
JCExpression parameterTypes = cx.treeMaker.NewArray(cx.treeMaker.Ident(cx.names.fromString(ConstPool.TYPE_CLASS)),
|
|
||||||
List.<JCExpression>nil(), m.snd.snd);
|
|
||||||
JCExpression thisIns = cx.treeMaker.Ident(cx.names.fromString(ConstPool.REF_THIS));
|
|
||||||
JCNewClass poolClass = cx.treeMaker.NewClass(null, List.<JCExpression>nil(), pool,
|
|
||||||
List.of(classType, methodName, parameterTypes, thisIns), null);
|
|
||||||
JCExpression addInjectMethod = nameToExpression(addPoolMethod);
|
|
||||||
JCMethodInvocation apply = cx.treeMaker.Apply(List.<JCExpression>nil(), addInjectMethod,
|
|
||||||
List.from(new JCExpression[] {poolClass}));
|
|
||||||
return cx.treeMaker.Exec(apply);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +1,18 @@
|
|||||||
package com.alibaba.testable.core.translator;
|
package com.alibaba.testable.core.translator;
|
||||||
|
|
||||||
|
import com.alibaba.testable.core.constant.ConstPool;
|
||||||
import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator;
|
import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator;
|
||||||
import com.alibaba.testable.core.generator.TestSetupMethodGenerator;
|
|
||||||
import com.alibaba.testable.core.generator.TestableRefFieldGenerator;
|
import com.alibaba.testable.core.generator.TestableRefFieldGenerator;
|
||||||
import com.alibaba.testable.core.model.TestableContext;
|
import com.alibaba.testable.core.model.TestableContext;
|
||||||
import com.alibaba.testable.core.constant.ConstPool;
|
|
||||||
import com.alibaba.testable.core.util.TypeUtil;
|
import com.alibaba.testable.core.util.TypeUtil;
|
||||||
import com.sun.tools.javac.tree.JCTree;
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
import com.sun.tools.javac.tree.JCTree.*;
|
import com.sun.tools.javac.tree.JCTree.*;
|
||||||
import com.sun.tools.javac.util.ListBuffer;
|
import com.sun.tools.javac.util.ListBuffer;
|
||||||
import com.sun.tools.javac.util.Name;
|
import com.sun.tools.javac.util.Name;
|
||||||
import com.sun.tools.javac.util.Pair;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Travel AST
|
* Travel AST
|
||||||
@ -24,21 +21,17 @@ import java.util.Arrays;
|
|||||||
*/
|
*/
|
||||||
public class EnableTestableTranslator extends BaseTranslator {
|
public class EnableTestableTranslator extends BaseTranslator {
|
||||||
|
|
||||||
private final TestableContext cx;
|
|
||||||
private final String testClassName;
|
private final String testClassName;
|
||||||
private final String sourceClassName;
|
private final String sourceClassName;
|
||||||
private final ListBuffer<Name> sourceClassIns = new ListBuffer<>();
|
private final ListBuffer<Name> sourceClassIns = new ListBuffer<>();
|
||||||
private final ListBuffer<String> privateOrFinalFields = new ListBuffer<>();
|
private final ListBuffer<String> privateOrFinalFields = new ListBuffer<>();
|
||||||
private final ListBuffer<String> privateMethods = new ListBuffer<>();
|
private final ListBuffer<String> privateMethods = new ListBuffer<>();
|
||||||
private final TestSetupMethodGenerator testSetupMethodGenerator;
|
|
||||||
private final PrivateAccessStatementGenerator privateAccessStatementGenerator;
|
private final PrivateAccessStatementGenerator privateAccessStatementGenerator;
|
||||||
private final TestableRefFieldGenerator testableRefFieldGenerator;
|
private final TestableRefFieldGenerator testableRefFieldGenerator;
|
||||||
|
|
||||||
public EnableTestableTranslator(String pkgName, String testClassName, TestableContext cx) {
|
public EnableTestableTranslator(String pkgName, String testClassName, TestableContext cx) {
|
||||||
this.testClassName = testClassName;
|
this.testClassName = testClassName;
|
||||||
this.sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
|
this.sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
|
||||||
this.cx = cx;
|
|
||||||
this.testSetupMethodGenerator = new TestSetupMethodGenerator(cx);
|
|
||||||
this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx);
|
this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx);
|
||||||
this.testableRefFieldGenerator = new TestableRefFieldGenerator(cx, pkgName + "." + testClassName);
|
this.testableRefFieldGenerator = new TestableRefFieldGenerator(cx, pkgName + "." + testClassName);
|
||||||
try {
|
try {
|
||||||
@ -55,7 +48,6 @@ public class EnableTestableTranslator extends BaseTranslator {
|
|||||||
privateMethods.add(m.getName());
|
privateMethods.add(m.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testSetupMethodGenerator.memberMethods.addAll(Arrays.asList(cls.getDeclaredMethods()));
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -93,13 +85,6 @@ public class EnableTestableTranslator extends BaseTranslator {
|
|||||||
for (JCAnnotation a : jcMethodDecl.mods.annotations) {
|
for (JCAnnotation a : jcMethodDecl.mods.annotations) {
|
||||||
if (a.type != null && ConstPool.ANNOTATION_TESTABLE_INJECT.equals(a.type.tsym.toString())) {
|
if (a.type != null && ConstPool.ANNOTATION_TESTABLE_INJECT.equals(a.type.tsym.toString())) {
|
||||||
TypeUtil.toPublicFlags(jcMethodDecl.getModifiers());
|
TypeUtil.toPublicFlags(jcMethodDecl.getModifiers());
|
||||||
ListBuffer<JCExpression> args = new ListBuffer<>();
|
|
||||||
for (JCVariableDecl p : jcMethodDecl.params) {
|
|
||||||
args.add(cx.treeMaker.Select(p.vartype, cx.names.fromString(ConstPool.CLASS_OF_TYPE)));
|
|
||||||
}
|
|
||||||
JCExpression retType = jcMethodDecl.restype == null ? null :
|
|
||||||
cx.treeMaker.Select(jcMethodDecl.restype, cx.names.fromString(ConstPool.CLASS_OF_TYPE));
|
|
||||||
testSetupMethodGenerator.injectMethods.add(Pair.of(jcMethodDecl.name, Pair.of(retType, args.toList())));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.visitMethodDef(jcMethodDecl);
|
super.visitMethodDef(jcMethodDecl);
|
||||||
@ -114,7 +99,6 @@ public class EnableTestableTranslator extends BaseTranslator {
|
|||||||
if (jcClassDecl.name.toString().equals(testClassName)) {
|
if (jcClassDecl.name.toString().equals(testClassName)) {
|
||||||
ListBuffer<JCTree> ndefs = new ListBuffer<>();
|
ListBuffer<JCTree> ndefs = new ListBuffer<>();
|
||||||
ndefs.addAll(jcClassDecl.defs);
|
ndefs.addAll(jcClassDecl.defs);
|
||||||
ndefs.add(testSetupMethodGenerator.fetch());
|
|
||||||
ndefs.add(testableRefFieldGenerator.fetch());
|
ndefs.add(testableRefFieldGenerator.fetch());
|
||||||
jcClassDecl.defs = ndefs.toList();
|
jcClassDecl.defs = ndefs.toList();
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
package com.alibaba.testable.core.util;
|
package com.alibaba.testable.core.util;
|
||||||
|
|
||||||
|
import com.alibaba.testable.core.constant.ConstPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author flin
|
* @author flin
|
||||||
*/
|
*/
|
||||||
public class TestableUtil {
|
public class TestableUtil {
|
||||||
|
|
||||||
private static final String TESTABLE_NE = "n.e";
|
public static String currentMemberMethodName(Object testClassRef) {
|
||||||
|
return currentMemberMethodName(testClassRef.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
public static String currentMemberMethodName() {
|
public static String currentMemberMethodName(Class<?> testClass) {
|
||||||
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
|
StackTraceElement[] stack = getMainThread().getStackTrace();
|
||||||
for (int i = 0; i < stack.length; i++) {
|
String testClassName = getRealClassName(testClass);
|
||||||
if (stack[i].getClassName().equals(TESTABLE_NE)) {
|
String sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
|
||||||
return stack[i + 1].getMethodName();
|
for (int i = stack.length - 1; i >= 0; i--) {
|
||||||
|
if (stack[i].getClassName().equals(sourceClassName)) {
|
||||||
|
return stack[i].getMethodName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@ -21,7 +27,7 @@ public class TestableUtil {
|
|||||||
return currentTestCaseName(testClassRef.getClass());
|
return currentTestCaseName(testClassRef.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String currentTestCaseName(Class testClass) {
|
public static String currentTestCaseName(Class<?> testClass) {
|
||||||
StackTraceElement[] stack = getMainThread().getStackTrace();
|
StackTraceElement[] stack = getMainThread().getStackTrace();
|
||||||
String testClassName = getRealClassName(testClass);
|
String testClassName = getRealClassName(testClass);
|
||||||
for (int i = stack.length - 1; i >= 0; i--) {
|
for (int i = stack.length - 1; i >= 0; i--) {
|
||||||
@ -32,7 +38,7 @@ public class TestableUtil {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getRealClassName(Class testClass) {
|
private static String getRealClassName(Class<?> testClass) {
|
||||||
String className = testClass.getName();
|
String className = testClass.getName();
|
||||||
int posOfInnerClass = className.lastIndexOf('$');
|
int posOfInnerClass = className.lastIndexOf('$');
|
||||||
return posOfInnerClass > 0 ? className.substring(0, posOfInnerClass) : className;
|
return posOfInnerClass > 0 ? className.substring(0, posOfInnerClass) : className;
|
||||||
|
@ -22,126 +22,11 @@ public class TypeUtil {
|
|||||||
modifiers.flags |= Modifier.PUBLIC;
|
modifiers.flags |= Modifier.PUBLIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Information of substitution method
|
|
||||||
*/
|
|
||||||
public static class TestableSubstitution {
|
|
||||||
public Class type; // target instance type to new / method return type
|
|
||||||
public Class[] parameterTypes; // constructor parameter types / member method parameter types
|
|
||||||
public Object targetObject; // object which provides substitution / object which provides substitution
|
|
||||||
public String methodName; // substitution method name / original member method name
|
|
||||||
|
|
||||||
public TestableSubstitution(Class type, String methodName, Class[] parameterTypes, Object targetObject) {
|
|
||||||
this.type = type;
|
|
||||||
this.methodName = methodName;
|
|
||||||
this.parameterTypes = parameterTypes;
|
|
||||||
this.targetObject = targetObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<TestableSubstitution> mockNewPool = new ArrayList<>();
|
|
||||||
private static List<TestableSubstitution> mockMemberPool = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* add item to constructor pool
|
|
||||||
*/
|
|
||||||
public static void addToConstructorPool(TestableSubstitution substitution) {
|
|
||||||
mockNewPool.add(substitution);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* add item to method pool
|
|
||||||
*/
|
|
||||||
public static void addToMemberMethodPool(TestableSubstitution substitution) {
|
|
||||||
mockMemberPool.add(substitution);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* substitution entry for new
|
|
||||||
*/
|
|
||||||
public static <T> T wrapNew(Class<T> classType, Object... parameters) {
|
|
||||||
Class[] cs = TypeUtil.getClassesFromObjects(parameters);
|
|
||||||
if (!mockNewPool.isEmpty()) {
|
|
||||||
try {
|
|
||||||
TestableSubstitution pi = getFromConstructorPool(classType, cs);
|
|
||||||
if (pi != null) {
|
|
||||||
Method m = pi.targetObject.getClass().getDeclaredMethod(pi.methodName, pi.parameterTypes);
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (T)m.invoke(pi.targetObject, parameters);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Constructor c = TypeUtil.getConstructorByParameterTypes(classType.getConstructors(), cs);
|
|
||||||
if (c != null) {
|
|
||||||
return (T)c.newInstance(parameters);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* substitution entry for member call
|
|
||||||
*/
|
|
||||||
public static <T> T wrapCall(Object targetObject, String methodName, Object... parameters) {
|
|
||||||
Class[] cs = TypeUtil.getClassesFromObjects(parameters);
|
|
||||||
if (!mockMemberPool.isEmpty()) {
|
|
||||||
try {
|
|
||||||
TestableSubstitution pi = getFromMemberMethodPool(methodName, cs);
|
|
||||||
if (pi != null) {
|
|
||||||
Method m = pi.targetObject.getClass().getDeclaredMethod(pi.methodName, pi.parameterTypes);
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (T)m.invoke(pi.targetObject, parameters);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Method m = TypeUtil.getMethodByNameAndParameterTypes(targetObject.getClass().getDeclaredMethods(), methodName, cs);
|
|
||||||
if (m != null) {
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (T)m.invoke(targetObject, parameters);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get from method pool by key
|
|
||||||
*/
|
|
||||||
private static TestableSubstitution getFromMemberMethodPool(String methodName, Class[] parameterTypes) {
|
|
||||||
for (TestableSubstitution f : mockMemberPool) {
|
|
||||||
if (f.methodName.equals(methodName) && TypeUtil.typeEquals(f.parameterTypes, parameterTypes)) {
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get from constructor pool by key
|
|
||||||
*/
|
|
||||||
private static TestableSubstitution getFromConstructorPool(Class type, Class[] parameterTypes) {
|
|
||||||
for (TestableSubstitution w : mockNewPool) {
|
|
||||||
if (w.type.equals(type) && TypeUtil.typeEquals(w.parameterTypes, parameterTypes)) {
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get classes of parameter objects
|
* get classes of parameter objects
|
||||||
*/
|
*/
|
||||||
public static Class[] getClassesFromObjects(Object[] parameterObjects) {
|
public static Class<?>[] getClassesFromObjects(Object[] parameterObjects) {
|
||||||
Class[] cs = new Class[parameterObjects.length];
|
Class<?>[] cs = new Class[parameterObjects.length];
|
||||||
for (int i = 0; i < cs.length; i++) {
|
for (int i = 0; i < cs.length; i++) {
|
||||||
cs[i] = parameterObjects[i].getClass();
|
cs[i] = parameterObjects[i].getClass();
|
||||||
}
|
}
|
||||||
@ -153,7 +38,7 @@ public class TypeUtil {
|
|||||||
*/
|
*/
|
||||||
public static Method getMethodByNameAndParameterTypes(Method[] availableMethods,
|
public static Method getMethodByNameAndParameterTypes(Method[] availableMethods,
|
||||||
String methodName,
|
String methodName,
|
||||||
Class[] parameterTypes) {
|
Class<?>[] parameterTypes) {
|
||||||
for (Method m : availableMethods) {
|
for (Method m : availableMethods) {
|
||||||
if (m.getName().equals(methodName) &&
|
if (m.getName().equals(methodName) &&
|
||||||
typeEquals(m.getParameterTypes(), parameterTypes)) {
|
typeEquals(m.getParameterTypes(), parameterTypes)) {
|
||||||
@ -164,22 +49,9 @@ public class TypeUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get constructor by parameter matching
|
* type equals
|
||||||
*/
|
*/
|
||||||
public static Constructor getConstructorByParameterTypes(Constructor<?>[] constructors,
|
public static boolean typeEquals(Class<?>[] classesLeft, Class<?>[] classesRight) {
|
||||||
Class[] parameterTypes) {
|
|
||||||
for (Constructor c : constructors) {
|
|
||||||
if (typeEquals(c.getParameterTypes(), parameterTypes)) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* type equeals
|
|
||||||
*/
|
|
||||||
public static boolean typeEquals(Class[] classesLeft, Class[] classesRight) {
|
|
||||||
if (classesLeft.length != classesRight.length) {
|
if (classesLeft.length != classesRight.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -197,7 +69,7 @@ public class TypeUtil {
|
|||||||
* @param factTypes fact types (can be primary type)
|
* @param factTypes fact types (can be primary type)
|
||||||
* @param userTypes user types
|
* @param userTypes user types
|
||||||
*/
|
*/
|
||||||
private static boolean fuzzyEqual(Class factTypes, Class userTypes) {
|
private static boolean fuzzyEqual(Class<?> factTypes, Class<?> userTypes) {
|
||||||
return (factTypes.equals(int.class) && userTypes.equals(Integer.class)) ||
|
return (factTypes.equals(int.class) && userTypes.equals(Integer.class)) ||
|
||||||
(factTypes.equals(long.class) && userTypes.equals(Long.class)) ||
|
(factTypes.equals(long.class) && userTypes.equals(Long.class)) ||
|
||||||
(factTypes.equals(short.class) && userTypes.equals(Short.class)) ||
|
(factTypes.equals(short.class) && userTypes.equals(Short.class)) ||
|
||||||
|
@ -1,121 +0,0 @@
|
|||||||
package n;
|
|
||||||
|
|
||||||
import static com.alibaba.testable.core.util.TypeUtil.wrapCall;
|
|
||||||
import static com.alibaba.testable.core.util.TypeUtil.wrapNew;
|
|
||||||
|
|
||||||
public final class e {
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct) {
|
|
||||||
return wrapNew(ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1) {
|
|
||||||
return wrapNew(ct, a1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2) {
|
|
||||||
return wrapNew(ct, a1, a2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3) {
|
|
||||||
return wrapNew(ct, a1, a2, a3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5, a6);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9, Object a10) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9, Object a10, Object a11) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T w(Class<T> ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9, Object a10, Object a11, Object a12) {
|
|
||||||
return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn) {
|
|
||||||
return wrapCall(o, mn);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1) {
|
|
||||||
return wrapCall(o, mn, a1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2) {
|
|
||||||
return wrapCall(o, mn, a1, a2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5, a6);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9, Object a10) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9, Object a10, Object a11) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
|
|
||||||
Object a8, Object a9, Object a10, Object a11, Object a12) {
|
|
||||||
return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user