diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/constant/ConstPool.java b/testable-agent/src/main/java/com/alibaba/testable/agent/constant/ConstPool.java index 63b259e..23c1f7d 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/constant/ConstPool.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/constant/ConstPool.java @@ -11,6 +11,7 @@ public class ConstPool { public static final String TEST_POSTFIX = "Test"; public static final String FIELD_TARGET_METHOD = "targetMethod"; + public static final String FIELD_TARGET_CLASS = "targetClass"; public static final String MOCK_WITH = "com.alibaba.testable.core.annotation.MockWith"; public static final String MOCK_METHOD = "com.alibaba.testable.core.annotation.MockMethod"; diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java b/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java index ad5d181..e81fbb0 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java @@ -9,6 +9,7 @@ import com.alibaba.testable.agent.util.AnnotationUtil; import com.alibaba.testable.agent.util.ClassUtil; import com.alibaba.testable.agent.util.GlobalConfig; import com.alibaba.testable.agent.util.StringUtil; +import com.alibaba.testable.core.model.NullType; import com.alibaba.testable.core.util.LogUtil; import com.alibaba.testable.core.model.MockDiagnose; import org.objectweb.asm.ClassReader; @@ -131,8 +132,7 @@ public class TestableClassTransformer implements ClassFileTransformer { } private void checkMethodAnnotation(ClassNode cn, List methodInfos, MethodNode mn) { - ImmutablePair methodDescPair = extractFirstParameter(mn.desc); - if (methodDescPair == null || mn.visibleAnnotations == null) { + if (mn.visibleAnnotations == null) { return; } for (AnnotationNode an : mn.visibleAnnotations) { @@ -141,6 +141,10 @@ public class TestableClassTransformer implements ClassFileTransformer { addMockConstructor(cn, methodInfos, mn); } else if (fullClassName.equals(ConstPool.MOCK_METHOD) || fullClassName.equals(ConstPool.TESTABLE_MOCK)) { + ImmutablePair methodDescPair = getMethodDescPair(mn, an); + if (methodDescPair == null) { + return; + } String targetMethod = AnnotationUtil.getAnnotationParameter( an, ConstPool.FIELD_TARGET_METHOD, mn.name, String.class); if (targetMethod.equals(ConstPool.CONSTRUCTOR)) { @@ -153,6 +157,16 @@ public class TestableClassTransformer implements ClassFileTransformer { } } + private ImmutablePair getMethodDescPair(MethodNode mn, AnnotationNode an) { + Class targetClass = AnnotationUtil.getAnnotationParameter( + an, ConstPool.FIELD_TARGET_CLASS, NullType.class, Class.class); + if (targetClass.equals(NullType.class)) { + return extractFirstParameter(mn.desc); + } else { + return ImmutablePair.of(ClassUtil.toByteCodeClassName(targetClass.getName()), mn.desc); + } + } + private void addMockMethod(List methodInfos, MethodNode mn, ImmutablePair methodDescPair, String targetMethod) { String targetClass = ClassUtil.toSlashSeparateFullClassName(methodDescPair.left); diff --git a/testable-agent/src/test/java/com/alibaba/testable/agent/transformer/TestableClassTransformerTest.java b/testable-agent/src/test/java/com/alibaba/testable/agent/transformer/TestableClassTransformerTest.java new file mode 100644 index 0000000..1e189f2 --- /dev/null +++ b/testable-agent/src/test/java/com/alibaba/testable/agent/transformer/TestableClassTransformerTest.java @@ -0,0 +1,23 @@ +package com.alibaba.testable.agent.transformer; + +import com.alibaba.testable.agent.tool.ImmutablePair; +import com.alibaba.testable.core.accessor.PrivateAccessor; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class TestableClassTransformerTest { + + private TestableClassTransformer testableClassTransformer = new TestableClassTransformer(); + + @Test + void should_split_parameters() { + ImmutablePair parameters = + PrivateAccessor.invoke(testableClassTransformer, "extractFirstParameter", "()"); + assertNull(parameters); + parameters = PrivateAccessor.invoke(testableClassTransformer, "extractFirstParameter", "(Lcom.alibaba.demo.Class;ILjava.lang.String;Z)"); + assertNotNull(parameters); + assertEquals("Lcom.alibaba.demo.Class;", parameters.left); + assertEquals("(ILjava.lang.String;Z)", parameters.right); + } +} diff --git a/testable-core/src/main/java/com/alibaba/testable/core/annotation/MockMethod.java b/testable-core/src/main/java/com/alibaba/testable/core/annotation/MockMethod.java index 7733ace..9bc1745 100644 --- a/testable-core/src/main/java/com/alibaba/testable/core/annotation/MockMethod.java +++ b/testable-core/src/main/java/com/alibaba/testable/core/annotation/MockMethod.java @@ -1,6 +1,6 @@ package com.alibaba.testable.core.annotation; -import javax.lang.model.type.NullType; +import com.alibaba.testable.core.model.NullType; import java.lang.annotation.*; /** diff --git a/testable-core/src/main/java/com/alibaba/testable/core/model/NullType.java b/testable-core/src/main/java/com/alibaba/testable/core/model/NullType.java new file mode 100644 index 0000000..afa5f7a --- /dev/null +++ b/testable-core/src/main/java/com/alibaba/testable/core/model/NullType.java @@ -0,0 +1,7 @@ +package com.alibaba.testable.core.model; + +/** + * @author flin + */ +public interface NullType { +}