diff --git a/demo/java-demo/src/main/java/com/alibaba/demo/lambda/StaticInstanceReference.java b/demo/java-demo/src/main/java/com/alibaba/demo/lambda/StaticInstanceReference.java index b85f056..b9bb40b 100644 --- a/demo/java-demo/src/main/java/com/alibaba/demo/lambda/StaticInstanceReference.java +++ b/demo/java-demo/src/main/java/com/alibaba/demo/lambda/StaticInstanceReference.java @@ -1,12 +1,5 @@ package com.alibaba.demo.lambda; -import java.math.BigDecimal; -import java.util.*; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; - /** * @author jim */ diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/lambda/CollectionListCodeDemoTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/lambda/CollectionListCodeDemoTest.java index 754cf3a..1a219d4 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/lambda/CollectionListCodeDemoTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/lambda/CollectionListCodeDemoTest.java @@ -1,8 +1,6 @@ package com.alibaba.demo.lambda; -import com.alibaba.testable.core.annotation.MockDiagnose; import com.alibaba.testable.core.annotation.MockInvoke; -import com.alibaba.testable.core.model.LogLevel; import org.junit.jupiter.api.Test; @@ -13,7 +11,6 @@ public class CollectionListCodeDemoTest { private final CollectionListCodeDemo instance = new CollectionListCodeDemo(); - //@MockDiagnose(LogLevel.VERBOSE) public static class Mock { @MockInvoke(targetClass = String.class, targetMethod = "contains") public boolean mockContains(CharSequence s) { diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/lambda/InvokeInterfaceDemoTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/lambda/InvokeInterfaceDemoTest.java index a185be1..f4b0ca9 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/lambda/InvokeInterfaceDemoTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/lambda/InvokeInterfaceDemoTest.java @@ -1,8 +1,6 @@ package com.alibaba.demo.lambda; -import com.alibaba.testable.core.annotation.MockDiagnose; import com.alibaba.testable.core.annotation.MockInvoke; -import com.alibaba.testable.core.model.LogLevel; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -20,7 +18,6 @@ public class InvokeInterfaceDemoTest { private final InvokeInterfaceDemo instance = new InvokeInterfaceDemo(); - //@MockDiagnose(LogLevel.VERBOSE) public static class Mock { @MockInvoke(targetClass = InvokeInterfaceDemo.ILambda.class, targetMethod = "run") diff --git a/demo/java-demo/src/test/java/com/alibaba/demo/lambda/StaticInstanceReferenceTest.java b/demo/java-demo/src/test/java/com/alibaba/demo/lambda/StaticInstanceReferenceTest.java index c539c35..4870ea0 100644 --- a/demo/java-demo/src/test/java/com/alibaba/demo/lambda/StaticInstanceReferenceTest.java +++ b/demo/java-demo/src/test/java/com/alibaba/demo/lambda/StaticInstanceReferenceTest.java @@ -1,8 +1,6 @@ package com.alibaba.demo.lambda; -import com.alibaba.testable.core.annotation.MockDiagnose; import com.alibaba.testable.core.annotation.MockInvoke; -import com.alibaba.testable.core.model.LogLevel; import org.junit.jupiter.api.Test; import static com.alibaba.testable.core.matcher.InvocationVerifier.verifyInvoked; @@ -15,16 +13,21 @@ public class StaticInstanceReferenceTest { private final StaticInstanceReference instance = new StaticInstanceReference(); - //@MockDiagnose(LogLevel.VERBOSE) public static class Mock { @MockInvoke(targetClass = StaticInstanceReference.StaticClassA.class, targetMethod = "doIt") private void mockDoIt() { } + + @MockInvoke(targetClass = StaticInstanceReference.StaticClassA.class) + private Integer function2(String s) { + return 2; + } } @Test public void shouldMockDoIt() { instance.staticMethodReference(); verifyInvoked("mockDoIt").withTimes(1); + verifyInvoked("function2").withTimes(1); } } diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java index cff25f3..a6d7833 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java @@ -11,10 +11,7 @@ import com.alibaba.testable.core.util.LogUtil; import org.objectweb.asm.*; import org.objectweb.asm.tree.*; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR; @@ -47,6 +44,10 @@ public class SourceClassHandler extends BaseClassHandler { @Override protected void transform(ClassNode cn) { LogUtil.diagnose("Found source class %s", cn.name); + if (injectMethods.isEmpty()) { + return; + } + Set memberInjectMethods = new HashSet(); Set newOperatorInjectMethods = new HashSet(); for (MethodInfo im : injectMethods) { @@ -57,7 +58,9 @@ public class SourceClassHandler extends BaseClassHandler { } } - resolveMethodReference(cn); + if (!memberInjectMethods.isEmpty()) { + resolveMethodReference(cn, memberInjectMethods); + } for (MethodNode m : cn.methods) { transformMethod(m, memberInjectMethods, newOperatorInjectMethods); @@ -355,11 +358,17 @@ public class SourceClassHandler extends BaseClassHandler { return handleList; } - private void resolveMethodReference(ClassNode cn) { + private void resolveMethodReference(ClassNode cn, Set mockedMethods) { List invokeDynamicList = new ArrayList(); for (MethodNode method : cn.methods) { List handleList = fetchInvokeDynamicHandle(method); - invokeDynamicList.addAll(handleList); + for (BsmArg arg : handleList) { + for (MethodInfo mi : mockedMethods) { + if (isMethodMocked(arg.getHandle(), mi)) { + invokeDynamicList.add(arg); + } + } + } } // process for method reference @@ -424,6 +433,19 @@ public class SourceClassHandler extends BaseClassHandler { } } + private boolean isMethodMocked(Handle targetHandle, MethodInfo mockMethodInfo) { + if (targetHandle.getTag() == Opcodes.H_INVOKEINTERFACE || targetHandle.getTag() == Opcodes.H_INVOKEVIRTUAL) { + String targetMockDesc = MethodUtil.addParameterAtBegin(mockMethodInfo.getDesc(), + ClassUtil.toByteCodeClassName(mockMethodInfo.getClazz())); + return mockMethodInfo.getClazz().equals(targetHandle.getOwner()) && + mockMethodInfo.getName().equals(targetHandle.getName()) && + targetMockDesc.equals(targetHandle.getDesc()); + } + return mockMethodInfo.getClazz().equals(targetHandle.getOwner()) && + mockMethodInfo.getName().equals(targetHandle.getName()) && + mockMethodInfo.getDesc().equals(targetHandle.getDesc()); + } + private void visitLocalVariableByArguments(MethodVisitor mv, final int initVar, Type[] argumentTypes, Label l0, Label l1) { int nextLocalVar = initVar; for (int i = 0; i < argumentTypes.length; i++) {