mirror of
https://github.com/alibaba/testable-mock.git
synced 2026-08-19 09:43:29 +08:00
feat: parse mock class considering MockContainer annotation
This commit is contained in:
@@ -14,12 +14,12 @@ public class DemoMultipleInherit {
|
||||
return "gin";
|
||||
}
|
||||
|
||||
private String suffix() {
|
||||
private String suffix(int some, String more, Object[] parameters) {
|
||||
return "_al";
|
||||
}
|
||||
|
||||
public String entry() {
|
||||
return prefix() + middle() + suffix();
|
||||
return prefix() + middle() + suffix(0, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class DemoMultipleInheritTest {
|
||||
|
||||
public static class SuffixMock {
|
||||
@MockInvoke(targetClass = DemoMultipleInherit.class)
|
||||
private String suffix() {
|
||||
private String suffix(int some, String more, Object[] parameters) {
|
||||
return "_it";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,11 +85,8 @@ public class MockClassHandler extends BaseClassWithContextHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < inheritedTypes.size(); i++) {
|
||||
String className = inheritedTypes.get(i).getClassName();
|
||||
String fieldName = INHERITED_REF + i;
|
||||
cn.fields.add(new FieldNode(ACC_PRIVATE | ACC_FINAL, fieldName,
|
||||
ClassUtil.toByteCodeClassName(className), null, null));
|
||||
for (Type inheritedType : inheritedTypes) {
|
||||
String className = inheritedType.getClassName();
|
||||
ClassNode inheritedClassNode = ClassUtil.getClassNode(className);
|
||||
if (inheritedClassNode == null) {
|
||||
throw new IllegalArgumentException("Failed to load class " + className);
|
||||
@@ -104,14 +101,14 @@ public class MockClassHandler extends BaseClassWithContextHandler {
|
||||
Type targetClass = AnnotationUtil.getAnnotationParameter(an, FIELD_TARGET_CLASS, null, Type.class);
|
||||
String targetMethod = AnnotationUtil.getAnnotationParameter(an, FIELD_TARGET_METHOD, null, String.class);
|
||||
String desc = (targetClass == null) ? mn.desc :
|
||||
MethodUtil.addParameterAtBegin(mn.desc, ClassUtil.toByteCodeClassName(targetClass.getClassName()));
|
||||
MethodUtil.addParameterAtBegin(mn.desc, ClassUtil.toByteCodeClassName(targetClass.getClassName()));
|
||||
String name = (targetMethod == null) ? mn.name : targetMethod;
|
||||
MethodNode mockMethod = new MethodNode(ACC_PUBLIC, name, desc, null, null);
|
||||
List<Byte> parameters = MethodUtil.getParameterTypes(mn.desc);
|
||||
int maxStack = 2;
|
||||
InsnList il = new InsnList();
|
||||
il.add(new VarInsnNode(ALOAD, 0));
|
||||
il.add(new FieldInsnNode(GETFIELD, ClassUtil.toSlashSeparatedName(cn.name), fieldName, ClassUtil.toByteCodeClassName(className)));
|
||||
il.add(new MethodInsnNode(INVOKESTATIC, ClassUtil.toSlashSeparatedName(className),
|
||||
GET_TESTABLE_REF, VOID_ARGS + ClassUtil.toByteCodeClassName(className), false));
|
||||
il.add(new VarInsnNode(ALOAD, 1));
|
||||
for (int pi = 2; pi < parameters.size() + 2; pi++) {
|
||||
ImmutablePair<Integer, Integer> codeAndStack = BytecodeUtil.getLoadParameterByteCode(parameters.get(pi - 2));
|
||||
|
||||
@@ -13,11 +13,11 @@ import org.objectweb.asm.tree.InnerClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.alibaba.testable.agent.constant.ByteCodeConst.TYPE_CLASS;
|
||||
import static com.alibaba.testable.agent.constant.ConstPool.CLASS_OBJECT;
|
||||
import static com.alibaba.testable.agent.constant.ConstPool.KOTLIN_POSTFIX_COMPANION;
|
||||
import static com.alibaba.testable.agent.constant.ConstPool.*;
|
||||
import static com.alibaba.testable.agent.util.ClassUtil.toJavaStyleClassName;
|
||||
import static com.alibaba.testable.agent.util.MethodUtil.isStatic;
|
||||
import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR;
|
||||
@@ -39,6 +39,7 @@ public class MockClassParser {
|
||||
for (MethodNode mn : getAllMethods(cn)) {
|
||||
addMethodWithAnnotationCheck(methodInfos, cn, mn);
|
||||
}
|
||||
handleMockContainerInherits(methodInfos, cn);
|
||||
return methodInfos;
|
||||
}
|
||||
|
||||
@@ -92,6 +93,30 @@ public class MockClassParser {
|
||||
return mns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take care of @MockContainer annotation
|
||||
*/
|
||||
private void handleMockContainerInherits(List<MethodInfo> methodInfos, ClassNode cn) {
|
||||
if (cn.visibleAnnotations != null) {
|
||||
for (AnnotationNode an : cn.visibleAnnotations) {
|
||||
if ((ClassUtil.toByteCodeClassName(ConstPool.MOCK_CONTAINER)).equals(an.desc)) {
|
||||
for (Object st : AnnotationUtil.getAnnotationParameter(an, FIELD_INHERITS,
|
||||
Collections.<Type>emptyList(), List.class)) {
|
||||
String superClassName = ((Type)st).getClassName();
|
||||
ClassNode superCn = ClassUtil.getClassNode(superClassName);
|
||||
if (superCn == null) {
|
||||
LogUtil.warn("failed to load class '%s' inherited by '%s'", superClassName, cn.name);
|
||||
continue;
|
||||
}
|
||||
for (MethodNode mn : getAllMethods(superCn)) {
|
||||
addMethodWithAnnotationCheck(methodInfos, cn, mn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addMethodWithAnnotationCheck(List<MethodInfo> methodInfos, ClassNode cn, MethodNode mn) {
|
||||
if (mn.visibleAnnotations == null) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user