diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java index 5a5fc02..1ef75ca 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java @@ -26,7 +26,7 @@ public class TestClassHandler extends BaseClassHandler { private static final String METHOD_CURRENT_TEST_CASE_NAME = "currentTestCaseName"; private static final String METHOD_CURRENT_SOURCE_METHOD_NAME = "currentSourceMethodName"; private static final String METHOD_RECORD_MOCK_INVOKE = "recordMockInvoke"; - private static final String SIGNATURE_CURRENT_TEST_CASE_NAME = "(Ljava/lang/Object;)Ljava/lang/String;"; + private static final String SIGNATURE_CURRENT_TEST_CASE_NAME = "(Ljava/lang/String;)Ljava/lang/String;"; private static final String SIGNATURE_CURRENT_SOURCE_METHOD_NAME = "()Ljava/lang/String;"; private static final String SIGNATURE_INVOKE_RECORDER_METHOD = "([Ljava/lang/Object;Z)V"; @@ -41,7 +41,7 @@ public class TestClassHandler extends BaseClassHandler { } for (MethodNode mn : cn.methods) { handleMockMethod(mn); - handleInstruction(mn); + handleInstruction(cn, mn); } } @@ -60,14 +60,31 @@ public class TestClassHandler extends BaseClassHandler { private void handleMockMethod(MethodNode mn) { if (isMockMethod(mn)) { - mn.access &= ~ACC_PRIVATE; - mn.access &= ~ACC_PROTECTED; - mn.access |= ACC_PUBLIC; - mn.access |= ACC_STATIC; + toPublicStatic(mn); injectInvokeRecorder(mn); } } + private void toPublicStatic(MethodNode mn) { + mn.access &= ~ACC_PRIVATE; + mn.access &= ~ACC_PROTECTED; + mn.access |= ACC_PUBLIC; + if ((mn.access & ACC_STATIC) == 0) { + mn.access |= ACC_STATIC; + // remote `this` reference + mn.localVariables.remove(0); + for (LocalVariableNode vn : mn.localVariables) { + vn.index--; + } + for (AbstractInsnNode in : mn.instructions) { + if (in.getOpcode() >= ILOAD && in.getOpcode() <= SASTORE) { + ((VarInsnNode)in).var--; + } + } + mn.maxLocals--; + } + } + private boolean isMockMethod(MethodNode mn) { if (mn.visibleAnnotations == null) { return false; @@ -82,14 +99,14 @@ public class TestClassHandler extends BaseClassHandler { return false; } - private void handleInstruction(MethodNode mn) { + private void handleInstruction(ClassNode cn, MethodNode mn) { AbstractInsnNode[] instructions = mn.instructions.toArray(); int i = 0; do { if (instructions[i].getOpcode() == GETSTATIC) { FieldInsnNode fieldInsnNode = (FieldInsnNode)instructions[i]; if (isTestableUtilField(fieldInsnNode)) { - instructions = replaceTestableUtilField(mn, instructions, fieldInsnNode.name, i); + instructions = replaceTestableUtilField(cn, mn, instructions, fieldInsnNode.name, i); } } i++; @@ -101,11 +118,11 @@ public class TestClassHandler extends BaseClassHandler { (fieldInsnNode.name.equals(FIELD_TEST_CASE) || fieldInsnNode.name.equals(FIELD_SOURCE_METHOD)); } - private AbstractInsnNode[] replaceTestableUtilField(MethodNode mn, AbstractInsnNode[] instructions, + private AbstractInsnNode[] replaceTestableUtilField(ClassNode cn, MethodNode mn, AbstractInsnNode[] instructions, String fieldName, int pos) { InsnList il = new InsnList(); if (FIELD_TEST_CASE.equals(fieldName)) { - il.add(new VarInsnNode(ALOAD, 0)); + il.add(new LdcInsnNode(ClassUtil.toDotSeparatedName(cn.name))); il.add(new MethodInsnNode(INVOKESTATIC, CLASS_TESTABLE_UTIL, METHOD_CURRENT_TEST_CASE_NAME, SIGNATURE_CURRENT_TEST_CASE_NAME, false)); } else if (FIELD_SOURCE_METHOD.equals(fieldName)) { @@ -123,7 +140,7 @@ public class TestClassHandler extends BaseClassHandler { InsnList il = new InsnList(); List types = ClassUtil.getParameterTypes(mn.desc); int size = types.size(); - int parameterOffset = 1; + int parameterOffset = 0; mn.maxStack += 1; il.add(getIntInsn(size)); il.add(new TypeInsnNode(ANEWARRAY, ClassUtil.CLASS_OBJECT)); diff --git a/testable-core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java b/testable-core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java index 213d318..356ac9d 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java @@ -28,17 +28,6 @@ public class TestableUtil { return Thread.currentThread().getStackTrace()[INDEX_OF_SOURCE_METHOD].getMethodName(); } - /** - * Get current test case method - * @param testClassRef usually `this` variable of the test class - * @return method name - */ - public static String currentTestCaseName(Object testClassRef) { - Class testClass = testClassRef.getClass(); - String testClassName = getOuterClassName(testClass.getName()); - return currentTestCaseName(testClassName); - } - /** * Get current test case method * @param testClassName name of current test class