This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 04c6b5f285e Add more test cases on shardingsphere-agent (#37632)
04c6b5f285e is described below

commit 04c6b5f285e58584dcf4b10d55c28fe616a699b2
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Jan 4 13:59:13 2026 +0800

    Add more test cases on shardingsphere-agent (#37632)
    
    * Add more test cases on shardingsphere-agent
    
    * Add more test cases on shardingsphere-agent
    
    * Add more test cases on shardingsphere-agent
    
    * Add more test cases on shardingsphere-agent
---
 .../executor/AdviceExecutorFactoryTest.java        | 113 ++++++++++
 .../type/ConstructorAdviceExecutorTest.java        | 134 ++++++++++++
 .../type/InstanceMethodAdviceExecutorTest.java     | 233 +++++++++++++++++++++
 .../type/StaticMethodAdviceExecutorTest.java       | 212 +++++++++++++++++++
 .../core/builder/AgentBuilderFactoryTest.java      |  59 +++++-
 .../impl/MethodAdvisorBuilderInterceptorTest.java  | 100 +++++++++
 6 files changed, 843 insertions(+), 8 deletions(-)

diff --git 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/AdviceExecutorFactoryTest.java
 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/AdviceExecutorFactoryTest.java
new file mode 100644
index 00000000000..7e1cf688582
--- /dev/null
+++ 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/AdviceExecutorFactoryTest.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.agent.core.advisor.executor;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatchers;
+import 
org.apache.shardingsphere.agent.core.advisor.config.AdvisorConfiguration;
+import 
org.apache.shardingsphere.agent.core.advisor.config.MethodAdvisorConfiguration;
+import 
org.apache.shardingsphere.agent.core.advisor.executor.type.ConstructorAdviceExecutor;
+import 
org.apache.shardingsphere.agent.core.advisor.executor.type.InstanceMethodAdviceExecutor;
+import 
org.apache.shardingsphere.agent.core.advisor.executor.type.StaticMethodAdviceExecutor;
+import 
org.apache.shardingsphere.agent.core.plugin.classloader.ClassLoaderContext;
+import org.apache.shardingsphere.fixture.advice.BarAdvice;
+import org.apache.shardingsphere.fixture.advice.FooAdvice;
+import org.apache.shardingsphere.fixture.targeted.TargetObjectFixture;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isA;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class AdviceExecutorFactoryTest {
+    
+    @AfterEach
+    void resetCache() throws ReflectiveOperationException {
+        ((Map<?, ?>) 
Plugins.getMemberAccessor().get(AdviceFactory.class.getDeclaredField("CACHED_ADVICES"),
 null)).clear();
+        ((Map<?, ?>) 
Plugins.getMemberAccessor().get(ClassLoaderContext.class.getDeclaredField("AGENT_CLASS_LOADERS"),
 null)).clear();
+    }
+    
+    @Test
+    void assertFindMatchedAdviceExecutorWithEmptyAdvisors() throws 
NoSuchMethodException {
+        AdvisorConfiguration advisorConfig = new 
AdvisorConfiguration(TargetObjectFixture.class.getName());
+        AdviceExecutorFactory factory = new AdviceExecutorFactory(new 
ClassLoaderContext(new URLClassLoader(new URL[0], getClass().getClassLoader()), 
Collections.emptyList()), advisorConfig);
+        assertFalse(factory.findMatchedAdviceExecutor(new 
MethodDescription.ForLoadedMethod(TargetObjectFixture.class.getMethod("call", 
List.class))).isPresent());
+    }
+    
+    @Test
+    void assertFindMatchedAdviceExecutorWithUnmatchedPointcut() throws 
NoSuchMethodException {
+        AdvisorConfiguration advisorConfig = new 
AdvisorConfiguration(TargetObjectFixture.class.getName());
+        MethodDescription.InDefinedShape instanceMethod = new 
MethodDescription.ForLoadedMethod(TargetObjectFixture.class.getMethod("call", 
List.class));
+        advisorConfig.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.none(), FooAdvice.class.getName(), 
"foo"));
+        AdviceExecutorFactory factory = new AdviceExecutorFactory(new 
ClassLoaderContext(new URLClassLoader(new URL[0], getClass().getClassLoader()), 
Collections.emptyList()), advisorConfig);
+        
assertFalse(factory.findMatchedAdviceExecutor(instanceMethod).isPresent());
+    }
+    
+    @Test
+    void assertFindMatchedAdviceExecutorWithConstructor() throws 
NoSuchMethodException {
+        MethodDescription.InDefinedShape constructor = new 
MethodDescription.ForLoadedConstructor(TargetObjectFixture.class.getDeclaredConstructor(List.class));
+        AdvisorConfiguration advisorConfig = new 
AdvisorConfiguration(TargetObjectFixture.class.getName());
+        advisorConfig.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.is(constructor), 
FooAdvice.class.getName(), "foo"));
+        advisorConfig.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.is(constructor), 
BarAdvice.class.getName(), "bar"));
+        AdviceExecutorFactory factory = new AdviceExecutorFactory(new 
ClassLoaderContext(new URLClassLoader(new URL[0], getClass().getClassLoader()), 
Collections.emptyList()), advisorConfig);
+        Optional<AdviceExecutor> actual = 
factory.findMatchedAdviceExecutor(constructor);
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), isA(ConstructorAdviceExecutor.class));
+    }
+    
+    @Test
+    void assertFindMatchedAdviceExecutorWithStaticMethod() throws 
NoSuchMethodException {
+        MethodDescription.InDefinedShape staticMethod = new 
MethodDescription.ForLoadedMethod(TargetObjectFixture.class.getMethod("staticCall",
 List.class));
+        AdvisorConfiguration advisorConfig = new 
AdvisorConfiguration(TargetObjectFixture.class.getName());
+        advisorConfig.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.is(staticMethod), 
FooAdvice.class.getName(), "foo"));
+        AdviceExecutorFactory factory = new AdviceExecutorFactory(new 
ClassLoaderContext(new URLClassLoader(new URL[0], getClass().getClassLoader()), 
Collections.emptyList()), advisorConfig);
+        Optional<AdviceExecutor> actual = 
factory.findMatchedAdviceExecutor(staticMethod);
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), isA(StaticMethodAdviceExecutor.class));
+    }
+    
+    @Test
+    void assertFindMatchedAdviceExecutorWithInstanceMethod() throws 
NoSuchMethodException {
+        MethodDescription.InDefinedShape instanceMethod = new 
MethodDescription.ForLoadedMethod(TargetObjectFixture.class.getMethod("call", 
List.class));
+        AdvisorConfiguration advisorConfig = new 
AdvisorConfiguration(TargetObjectFixture.class.getName());
+        advisorConfig.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.is(instanceMethod), 
FooAdvice.class.getName(), "foo"));
+        AdviceExecutorFactory factory = new AdviceExecutorFactory(new 
ClassLoaderContext(new URLClassLoader(new URL[0], getClass().getClassLoader()), 
Collections.emptyList()), advisorConfig);
+        Optional<AdviceExecutor> actual = 
factory.findMatchedAdviceExecutor(instanceMethod);
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), isA(InstanceMethodAdviceExecutor.class));
+    }
+    
+    @Test
+    void assertFindMatchedAdviceExecutorWithAbstractMethod() throws 
NoSuchMethodException {
+        MethodDescription.InDefinedShape abstractMethod = new 
MethodDescription.ForLoadedMethod(Runnable.class.getMethod("run"));
+        AdvisorConfiguration advisorConfig = new 
AdvisorConfiguration(Runnable.class.getName());
+        advisorConfig.getAdvisors().add(new MethodAdvisorConfiguration(target 
-> true, FooAdvice.class.getName(), "foo"));
+        AdviceExecutorFactory factory = new AdviceExecutorFactory(new 
ClassLoaderContext(new URLClassLoader(new URL[0], getClass().getClassLoader()), 
Collections.emptyList()), advisorConfig);
+        
assertFalse(factory.findMatchedAdviceExecutor(abstractMethod).isPresent());
+    }
+}
diff --git 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/ConstructorAdviceExecutorTest.java
 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/ConstructorAdviceExecutorTest.java
new file mode 100644
index 00000000000..95d1f765f04
--- /dev/null
+++ 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/ConstructorAdviceExecutorTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.agent.core.advisor.executor.type;
+
+import net.bytebuddy.dynamic.DynamicType.Builder;
+import 
net.bytebuddy.dynamic.DynamicType.Builder.MethodDefinition.ImplementationDefinition;
+import 
net.bytebuddy.dynamic.DynamicType.Builder.MethodDefinition.ReceiverTypeDefinition;
+import org.apache.shardingsphere.agent.api.advice.TargetAdviceObject;
+import org.apache.shardingsphere.agent.api.advice.type.ConstructorAdvice;
+import org.apache.shardingsphere.agent.api.plugin.AgentPluginEnable;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class ConstructorAdviceExecutorTest {
+    
+    @Test
+    void assertAdviceInvokeEnabledAdvice() {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<ConstructorAdvice>> advices = 
Collections.singletonMap("foo", Arrays.asList(new 
RecordingConstructorAdvice(queue, true), new 
PluginDisabledConstructorAdvice(queue)));
+        new ConstructorAdviceExecutor(advices).advice(new 
SimpleTargetAdviceObject(), new Object[]{queue});
+        assertThat(queue, is(Collections.singletonList("foo constructor")));
+    }
+    
+    @Test
+    void assertAdviceCatchException() {
+        Map<String, Collection<ConstructorAdvice>> advices = 
Collections.singletonMap("foo", Collections.singletonList(new 
ThrowingConstructorAdvice()));
+        ConstructorAdviceExecutor executor = new 
ConstructorAdviceExecutor(advices);
+        assertDoesNotThrow(() -> executor.advice(new 
SimpleTargetAdviceObject(), new Object[]{new LinkedList<>()}));
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    void assertIntercept() {
+        Builder<?> builder = mock(Builder.class);
+        ImplementationDefinition<?> implementationDefinition = 
mock(ImplementationDefinition.class);
+        ReceiverTypeDefinition<?> intercepted = 
mock(ReceiverTypeDefinition.class);
+        when(builder.constructor(any())).thenReturn((ImplementationDefinition) 
implementationDefinition);
+        
when(implementationDefinition.intercept(any())).thenReturn((ReceiverTypeDefinition)
 intercepted);
+        ConstructorAdviceExecutor executor = new 
ConstructorAdviceExecutor(Collections.emptyMap());
+        assertThat(executor.intercept(builder, mock()), is(intercepted));
+    }
+    
+    private static final class RecordingConstructorAdvice implements 
ConstructorAdvice, AgentPluginEnable {
+        
+        private final List<String> queue;
+        
+        private final boolean pluginEnabled;
+        
+        RecordingConstructorAdvice(final List<String> queue, final boolean 
pluginEnabled) {
+            this.queue = queue;
+            this.pluginEnabled = pluginEnabled;
+        }
+        
+        @Override
+        public boolean isPluginEnabled() {
+            return pluginEnabled;
+        }
+        
+        @Override
+        public void onConstructor(final TargetAdviceObject target, final 
Object[] args, final String pluginType) {
+            queue.add(pluginType + " constructor");
+        }
+    }
+    
+    private static final class PluginDisabledConstructorAdvice implements 
ConstructorAdvice, AgentPluginEnable {
+        
+        private final List<String> queue;
+        
+        PluginDisabledConstructorAdvice(final List<String> queue) {
+            this.queue = queue;
+        }
+        
+        @Override
+        public boolean isPluginEnabled() {
+            return false;
+        }
+        
+        @Override
+        public void onConstructor(final TargetAdviceObject target, final 
Object[] args, final String pluginType) {
+            queue.add("disabled");
+        }
+    }
+    
+    private static final class ThrowingConstructorAdvice implements 
ConstructorAdvice {
+        
+        @Override
+        public void onConstructor(final TargetAdviceObject target, final 
Object[] args, final String pluginType) {
+            throw new IllegalStateException("error");
+        }
+    }
+    
+    private static final class SimpleTargetAdviceObject implements 
TargetAdviceObject {
+        
+        private Object attachment;
+        
+        @Override
+        public Object getAttachment() {
+            return attachment;
+        }
+        
+        @Override
+        public void setAttachment(final Object attachment) {
+            this.attachment = attachment;
+        }
+    }
+}
diff --git 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/InstanceMethodAdviceExecutorTest.java
 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/InstanceMethodAdviceExecutorTest.java
new file mode 100644
index 00000000000..cc23ee6adde
--- /dev/null
+++ 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/InstanceMethodAdviceExecutorTest.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.agent.core.advisor.executor.type;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.dynamic.DynamicType.Builder;
+import 
net.bytebuddy.dynamic.DynamicType.Builder.MethodDefinition.ImplementationDefinition;
+import 
net.bytebuddy.dynamic.DynamicType.Builder.MethodDefinition.ReceiverTypeDefinition;
+import org.apache.shardingsphere.agent.api.advice.TargetAdviceMethod;
+import org.apache.shardingsphere.agent.api.advice.TargetAdviceObject;
+import org.apache.shardingsphere.agent.api.advice.type.InstanceMethodAdvice;
+import org.apache.shardingsphere.agent.api.plugin.AgentPluginEnable;
+import org.apache.shardingsphere.agent.core.advisor.executor.AdviceExecutor;
+import org.apache.shardingsphere.fixture.targeted.TargetObjectFixture;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class InstanceMethodAdviceExecutorTest {
+    
+    @Test
+    void assertAdviceWhenCallableSucceeded() throws 
ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<InstanceMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
RecordingInstanceMethodAdvice(queue, "plain")));
+        advices.put("bar", Collections.singletonList(new 
ConfigurableInstanceMethodAdvice(queue, "config", false, false, false, false)));
+        InstanceMethodAdviceExecutor executor = new 
InstanceMethodAdviceExecutor(advices);
+        Method method = TargetObjectFixture.class.getMethod("call", 
List.class);
+        Callable<Object> callable = () -> {
+            queue.add("origin call");
+            return "result";
+        };
+        assertThat(executor.advice(new SimpleTargetAdviceObject(), method, new 
Object[]{queue}, callable), is("result"));
+        assertThat(queue, is(Arrays.asList("plain before foo", "origin call", 
"plain after foo")));
+    }
+    
+    @Test
+    void assertAdviceWhenCallableThrows() throws ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<InstanceMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
RecordingInstanceMethodAdvice(queue, "plain")));
+        advices.put("bar", Collections.singletonList(new 
ConfigurableInstanceMethodAdvice(queue, "config", true, false, false, true)));
+        InstanceMethodAdviceExecutor executor = new 
InstanceMethodAdviceExecutor(advices);
+        Method method = 
TargetObjectFixture.class.getMethod("callWhenExceptionThrown", List.class);
+        Callable<Object> callable = () -> {
+            throw new IllegalStateException("callable error");
+        };
+        assertThrows(IllegalStateException.class, () -> executor.advice(new 
SimpleTargetAdviceObject(), method, new Object[]{queue}, callable));
+        assertThat(queue, is(Arrays.asList("plain before foo", "config before 
bar", "plain throw foo", "plain after foo", "config after bar")));
+    }
+    
+    @Test
+    void assertAdviceWhenCallableThrowsWithoutOnThrowingException() throws 
ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<InstanceMethodAdvice>> advices = new 
LinkedHashMap<>(1, 1F);
+        advices.put("foo", Collections.singletonList(new 
RecordingInstanceMethodAdvice(queue, "plain")));
+        InstanceMethodAdviceExecutor executor = new 
InstanceMethodAdviceExecutor(advices);
+        Method method = 
TargetObjectFixture.class.getMethod("callWhenExceptionThrown", List.class);
+        Callable<Object> callable = () -> {
+            throw new IllegalStateException("callable error");
+        };
+        assertThrows(IllegalStateException.class, () -> executor.advice(new 
SimpleTargetAdviceObject(), method, new Object[]{queue}, callable));
+        assertThat(queue, is(Arrays.asList("plain before foo", "plain throw 
foo", "plain after foo")));
+    }
+    
+    @Test
+    void assertAdviceWhenCallableThrowsWithPluginDisabled() throws 
ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<InstanceMethodAdvice>> advices = new 
LinkedHashMap<>(1, 1F);
+        advices.put("foo", Collections.singletonList(new 
ConfigurableInstanceMethodAdvice(queue, "disabled", false, false, false, 
false)));
+        InstanceMethodAdviceExecutor executor = new 
InstanceMethodAdviceExecutor(advices);
+        Method method = 
TargetObjectFixture.class.getMethod("callWhenExceptionThrown", List.class);
+        Callable<Object> callable = () -> {
+            throw new IllegalStateException("callable error");
+        };
+        assertThrows(IllegalStateException.class, () -> executor.advice(new 
SimpleTargetAdviceObject(), method, new Object[]{queue}, callable));
+        assertThat(queue, is(Collections.emptyList()));
+    }
+    
+    @Test
+    void assertAdviceWhenBeforeThrows() throws ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<InstanceMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
ConfigurableInstanceMethodAdvice(queue, "first", true, true, false, false)));
+        advices.put("bar", Collections.singletonList(new 
RecordingInstanceMethodAdvice(queue, "second")));
+        InstanceMethodAdviceExecutor executor = new 
InstanceMethodAdviceExecutor(advices);
+        Method method = TargetObjectFixture.class.getMethod("call", 
List.class);
+        Callable<Object> callable = () -> {
+            queue.add("origin call");
+            return "result";
+        };
+        assertThat(executor.advice(new SimpleTargetAdviceObject(), method, new 
Object[]{queue}, callable), is("result"));
+        assertThat(queue, is(Arrays.asList("origin call", "first after foo", 
"second after bar")));
+    }
+    
+    @Test
+    void assertAdviceWhenAfterThrows() throws ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<InstanceMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
ConfigurableInstanceMethodAdvice(queue, "first", true, false, true, false)));
+        advices.put("bar", Collections.singletonList(new 
RecordingInstanceMethodAdvice(queue, "second")));
+        InstanceMethodAdviceExecutor executor = new 
InstanceMethodAdviceExecutor(advices);
+        Method method = TargetObjectFixture.class.getMethod("call", 
List.class);
+        Callable<Object> callable = () -> {
+            queue.add("origin call");
+            return "result";
+        };
+        assertThat(executor.advice(new SimpleTargetAdviceObject(), method, new 
Object[]{queue}, callable), is("result"));
+        assertThat(queue, is(Arrays.asList("first before foo", "second before 
bar", "origin call")));
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    void assertIntercept() {
+        Builder<?> builder = mock(Builder.class);
+        ImplementationDefinition<?> implementationDefinition = 
mock(ImplementationDefinition.class);
+        ReceiverTypeDefinition<?> intercepted = 
mock(ReceiverTypeDefinition.class);
+        MethodDescription methodDescription = mock(MethodDescription.class);
+        when(builder.method(any())).thenReturn((ImplementationDefinition) 
implementationDefinition);
+        
when(implementationDefinition.intercept(any())).thenReturn((ReceiverTypeDefinition)
 intercepted);
+        AdviceExecutor executor = new 
InstanceMethodAdviceExecutor(Collections.emptyMap());
+        Builder<?> actual = executor.intercept(builder, methodDescription);
+        assertThat(actual, is(intercepted));
+    }
+    
+    @RequiredArgsConstructor
+    private static final class RecordingInstanceMethodAdvice implements 
InstanceMethodAdvice {
+        
+        private final List<String> queue;
+        
+        private final String label;
+        
+        @Override
+        public void beforeMethod(final TargetAdviceObject target, final 
TargetAdviceMethod method, final Object[] args, final String pluginType) {
+            queue.add(label + " before " + pluginType);
+        }
+        
+        @Override
+        public void afterMethod(final TargetAdviceObject target, final 
TargetAdviceMethod method, final Object[] args, final Object result, final 
String pluginType) {
+            queue.add(label + " after " + pluginType);
+        }
+        
+        @Override
+        public void onThrowing(final TargetAdviceObject target, final 
TargetAdviceMethod method, final Object[] args, final Throwable throwable, 
final String pluginType) {
+            queue.add(label + " throw " + pluginType);
+        }
+    }
+    
+    @RequiredArgsConstructor
+    private static final class ConfigurableInstanceMethodAdvice implements 
InstanceMethodAdvice, AgentPluginEnable {
+        
+        private final List<String> queue;
+        
+        private final String label;
+        
+        private final boolean pluginEnabled;
+        
+        private final boolean throwBefore;
+        
+        private final boolean throwAfter;
+        
+        private final boolean throwOnThrow;
+        
+        @Override
+        public boolean isPluginEnabled() {
+            return pluginEnabled;
+        }
+        
+        @Override
+        public void beforeMethod(final TargetAdviceObject target, final 
TargetAdviceMethod method, final Object[] args, final String pluginType) {
+            if (throwBefore) {
+                throw new IllegalStateException("before");
+            }
+            queue.add(label + " before " + pluginType);
+        }
+        
+        @Override
+        public void afterMethod(final TargetAdviceObject target, final 
TargetAdviceMethod method, final Object[] args, final Object result, final 
String pluginType) {
+            if (throwAfter) {
+                throw new IllegalStateException("after");
+            }
+            queue.add(label + " after " + pluginType);
+        }
+        
+        @Override
+        public void onThrowing(final TargetAdviceObject target, final 
TargetAdviceMethod method, final Object[] args, final Throwable throwable, 
final String pluginType) {
+            if (throwOnThrow) {
+                throw new IllegalStateException("throw");
+            }
+            queue.add(label + " throw " + pluginType);
+        }
+    }
+    
+    @Getter
+    @Setter
+    private static final class SimpleTargetAdviceObject implements 
TargetAdviceObject {
+        
+        private Object attachment;
+    }
+}
diff --git 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/StaticMethodAdviceExecutorTest.java
 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/StaticMethodAdviceExecutorTest.java
new file mode 100644
index 00000000000..299a5ac2723
--- /dev/null
+++ 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/executor/type/StaticMethodAdviceExecutorTest.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.agent.core.advisor.executor.type;
+
+import lombok.RequiredArgsConstructor;
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.dynamic.DynamicType.Builder;
+import 
net.bytebuddy.dynamic.DynamicType.Builder.MethodDefinition.ImplementationDefinition;
+import 
net.bytebuddy.dynamic.DynamicType.Builder.MethodDefinition.ReceiverTypeDefinition;
+import org.apache.shardingsphere.agent.api.advice.TargetAdviceMethod;
+import org.apache.shardingsphere.agent.api.advice.type.StaticMethodAdvice;
+import org.apache.shardingsphere.agent.api.plugin.AgentPluginEnable;
+import org.apache.shardingsphere.agent.core.advisor.executor.AdviceExecutor;
+import org.apache.shardingsphere.fixture.targeted.TargetObjectFixture;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class StaticMethodAdviceExecutorTest {
+    
+    @Test
+    void assertAdviceWhenCallableSucceeded() throws 
ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<StaticMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
RecordingStaticMethodAdvice(queue, "plain")));
+        advices.put("bar", Collections.singletonList(new 
ConfigurableStaticMethodAdvice(queue, "config", false, false, false, false)));
+        StaticMethodAdviceExecutor executor = new 
StaticMethodAdviceExecutor(advices);
+        Method method = TargetObjectFixture.class.getMethod("staticCall", 
List.class);
+        Callable<Object> callable = () -> {
+            queue.add("origin call");
+            return "result";
+        };
+        Object actualResult = executor.advice(TargetObjectFixture.class, 
method, new Object[]{queue}, callable);
+        assertThat(actualResult, is("result"));
+        assertThat(queue, is(Arrays.asList("plain before foo", "origin call", 
"plain after foo")));
+    }
+    
+    @Test
+    void assertAdviceWhenCallableThrows() throws ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<StaticMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
RecordingStaticMethodAdvice(queue, "plain")));
+        advices.put("bar", Collections.singletonList(new 
ConfigurableStaticMethodAdvice(queue, "config", true, false, false, true)));
+        StaticMethodAdviceExecutor executor = new 
StaticMethodAdviceExecutor(advices);
+        Method method = 
TargetObjectFixture.class.getMethod("staticCallWhenExceptionThrown", 
List.class);
+        Callable<Object> callable = () -> {
+            throw new IllegalStateException("callable error");
+        };
+        assertThrows(IllegalStateException.class, () -> 
executor.advice(TargetObjectFixture.class, method, new Object[]{queue}, 
callable));
+        assertThat(queue, is(Arrays.asList("plain before foo", "config before 
bar", "plain throw foo", "plain after foo", "config after bar")));
+    }
+    
+    @Test
+    void assertAdviceWhenCallableThrowsWithPluginDisabled() throws 
ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<StaticMethodAdvice>> advices = 
Collections.singletonMap(
+                "foo", Collections.singletonList(new 
ConfigurableStaticMethodAdvice(queue, "disabled", false, false, false, false)));
+        StaticMethodAdviceExecutor executor = new 
StaticMethodAdviceExecutor(advices);
+        Method method = 
TargetObjectFixture.class.getMethod("staticCallWhenExceptionThrown", 
List.class);
+        Callable<Object> callable = () -> {
+            throw new IllegalStateException("callable error");
+        };
+        assertThrows(IllegalStateException.class, () -> 
executor.advice(TargetObjectFixture.class, method, new Object[]{queue}, 
callable));
+        assertTrue(queue.isEmpty());
+    }
+    
+    @Test
+    void assertAdviceWhenBeforeThrows() throws ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<StaticMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
ConfigurableStaticMethodAdvice(queue, "first", true, true, false, false)));
+        advices.put("bar", Collections.singletonList(new 
RecordingStaticMethodAdvice(queue, "second")));
+        StaticMethodAdviceExecutor executor = new 
StaticMethodAdviceExecutor(advices);
+        Method method = TargetObjectFixture.class.getMethod("staticCall", 
List.class);
+        Callable<Object> callable = () -> {
+            queue.add("origin call");
+            return "result";
+        };
+        Object actualResult = executor.advice(TargetObjectFixture.class, 
method, new Object[]{queue}, callable);
+        assertThat(actualResult, is("result"));
+        assertThat(queue, is(Arrays.asList("origin call", "first after foo", 
"second after bar")));
+    }
+    
+    @Test
+    void assertAdviceWhenAfterThrows() throws ReflectiveOperationException {
+        List<String> queue = new LinkedList<>();
+        Map<String, Collection<StaticMethodAdvice>> advices = new 
LinkedHashMap<>(2, 1F);
+        advices.put("foo", Collections.singletonList(new 
ConfigurableStaticMethodAdvice(queue, "first", true, false, true, false)));
+        advices.put("bar", Collections.singletonList(new 
RecordingStaticMethodAdvice(queue, "second")));
+        StaticMethodAdviceExecutor executor = new 
StaticMethodAdviceExecutor(advices);
+        Method method = TargetObjectFixture.class.getMethod("staticCall", 
List.class);
+        Callable<Object> callable = () -> {
+            queue.add("origin call");
+            return "result";
+        };
+        Object actualResult = executor.advice(TargetObjectFixture.class, 
method, new Object[]{queue}, callable);
+        assertThat(actualResult, is("result"));
+        assertThat(queue, is(Arrays.asList("first before foo", "second before 
bar", "origin call")));
+    }
+    
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Test
+    void assertIntercept() {
+        Builder<?> builder = mock(Builder.class);
+        ImplementationDefinition<?> implementationDefinition = 
mock(ImplementationDefinition.class);
+        ReceiverTypeDefinition<?> intercepted = 
mock(ReceiverTypeDefinition.class);
+        MethodDescription methodDescription = mock(MethodDescription.class);
+        when(builder.method(any())).thenReturn((ImplementationDefinition) 
implementationDefinition);
+        
when(implementationDefinition.intercept(any())).thenReturn((ReceiverTypeDefinition)
 intercepted);
+        AdviceExecutor executor = new 
StaticMethodAdviceExecutor(Collections.emptyMap());
+        assertThat(executor.intercept(builder, methodDescription), 
is(intercepted));
+    }
+    
+    @RequiredArgsConstructor
+    private static final class RecordingStaticMethodAdvice implements 
StaticMethodAdvice {
+        
+        private final List<String> queue;
+        
+        private final String label;
+        
+        @Override
+        public void beforeMethod(final Class<?> clazz, final 
TargetAdviceMethod method, final Object[] args, final String pluginType) {
+            queue.add(label + " before " + pluginType);
+        }
+        
+        @Override
+        public void afterMethod(final Class<?> clazz, final TargetAdviceMethod 
method, final Object[] args, final Object result, final String pluginType) {
+            queue.add(label + " after " + pluginType);
+        }
+        
+        @Override
+        public void onThrowing(final Class<?> clazz, final TargetAdviceMethod 
method, final Object[] args, final Throwable throwable, final String 
pluginType) {
+            queue.add(label + " throw " + pluginType);
+        }
+    }
+    
+    @RequiredArgsConstructor
+    private static final class ConfigurableStaticMethodAdvice implements 
StaticMethodAdvice, AgentPluginEnable {
+        
+        private final List<String> queue;
+        
+        private final String label;
+        
+        private final boolean pluginEnabled;
+        
+        private final boolean throwBefore;
+        
+        private final boolean throwAfter;
+        
+        private final boolean throwOnThrow;
+        
+        @Override
+        public boolean isPluginEnabled() {
+            return pluginEnabled;
+        }
+        
+        @Override
+        public void beforeMethod(final Class<?> clazz, final 
TargetAdviceMethod method, final Object[] args, final String pluginType) {
+            if (throwBefore) {
+                throw new IllegalStateException("before");
+            }
+            queue.add(label + " before " + pluginType);
+        }
+        
+        @Override
+        public void afterMethod(final Class<?> clazz, final TargetAdviceMethod 
method, final Object[] args, final Object result, final String pluginType) {
+            if (throwAfter) {
+                throw new IllegalStateException("after");
+            }
+            queue.add(label + " after " + pluginType);
+        }
+        
+        @Override
+        public void onThrowing(final Class<?> clazz, final TargetAdviceMethod 
method, final Object[] args, final Throwable throwable, final String 
pluginType) {
+            if (throwOnThrow) {
+                throw new IllegalStateException("throw");
+            }
+            queue.add(label + " throw " + pluginType);
+        }
+    }
+}
diff --git 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/builder/AgentBuilderFactoryTest.java
 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/builder/AgentBuilderFactoryTest.java
index e51306b373d..5d47e5360b6 100644
--- 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/builder/AgentBuilderFactoryTest.java
+++ 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/builder/AgentBuilderFactoryTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.agent.core.builder;
 import net.bytebuddy.agent.ByteBuddyAgent;
 import net.bytebuddy.agent.builder.AgentBuilder;
 import net.bytebuddy.agent.builder.ResettableClassFileTransformer;
+import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
 import net.bytebuddy.matcher.ElementMatchers;
 import 
org.apache.shardingsphere.agent.core.advisor.config.AdvisorConfiguration;
 import 
org.apache.shardingsphere.agent.core.advisor.config.MethodAdvisorConfiguration;
@@ -41,19 +42,28 @@ import static org.hamcrest.MatcherAssert.assertThat;
 
 class AgentBuilderFactoryTest {
     
+    private static final String TARGET_CLASS_NAME = 
"org.apache.shardingsphere.fixture.targeted.AgentBuilderFactoryTestTarget";
+    
     private static ResettableClassFileTransformer agent;
     
+    private static Class<?> targetClass;
+    
     @BeforeAll
     static void setup() {
         ByteBuddyAgent.install();
-        AdvisorConfiguration advisorConfig = createAdvisorConfiguration();
+        AdvisorConfiguration advisorConfig = 
createAdvisorConfiguration(TARGET_CLASS_NAME);
         Map<String, AdvisorConfiguration> advisorConfigs = 
Collections.singletonMap(advisorConfig.getTargetClassName(), advisorConfig);
         AgentBuilder agentBuilder = 
AgentBuilderFactory.create(Collections.emptyMap(), Collections.emptyList(), 
advisorConfigs, true);
         agent = agentBuilder.installOnByteBuddyAgent();
+        targetClass = new 
net.bytebuddy.ByteBuddy().redefine(TargetObjectFixture.class)
+                .name(TARGET_CLASS_NAME)
+                .make()
+                .load(AgentBuilderFactoryTest.class.getClassLoader(), 
ClassLoadingStrategy.Default.INJECTION)
+                .getLoaded();
     }
     
-    private static AdvisorConfiguration createAdvisorConfiguration() {
-        AdvisorConfiguration result = new 
AdvisorConfiguration("org.apache.shardingsphere.fixture.targeted.TargetObjectFixture");
+    private static AdvisorConfiguration createAdvisorConfiguration(final 
String targetClassName) {
+        AdvisorConfiguration result = new 
AdvisorConfiguration(targetClassName);
         result.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(1)),
 FooAdvice.class.getName(), "FIXTURE"));
         result.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(1)),
 BarAdvice.class.getName(), "FIXTURE"));
         result.getAdvisors().add(new 
MethodAdvisorConfiguration(ElementMatchers.named("call"), 
FooAdvice.class.getName(), "FIXTURE"));
@@ -75,14 +85,15 @@ class AgentBuilderFactoryTest {
     @Test
     void assertAdviceConstructor() {
         List<String> queue = new LinkedList<>();
-        new TargetObjectFixture(queue);
+        invokeConstructor(queue);
         assertThat(queue, is(Arrays.asList("on constructor", "foo 
constructor", "bar constructor")));
     }
     
     @Test
     void assertAdviceInstanceMethod() {
         List<String> queue = new LinkedList<>();
-        new TargetObjectFixture(new LinkedList<>()).call(queue);
+        invokeConstructor(new LinkedList<>());
+        invokeInstance("call", queue);
         assertThat(queue, is(Arrays.asList("foo before instance method", "bar 
before instance method", "on instance method", "foo after instance method", 
"bar after instance method")));
     }
     
@@ -90,7 +101,8 @@ class AgentBuilderFactoryTest {
     void assertAdviceInstanceMethodWhenExceptionThrown() {
         List<String> queue = new LinkedList<>();
         try {
-            new TargetObjectFixture(new 
LinkedList<>()).callWhenExceptionThrown(queue);
+            invokeConstructor(new LinkedList<>());
+            invokeInstance("callWhenExceptionThrown", queue);
         } catch (final UnsupportedOperationException ignored) {
         }
         assertThat(queue, is(Arrays.asList("foo before instance method", "bar 
before instance method",
@@ -100,7 +112,7 @@ class AgentBuilderFactoryTest {
     @Test
     void assertAdviceStaticMethod() {
         List<String> queue = new LinkedList<>();
-        TargetObjectFixture.staticCall(queue);
+        invokeStatic("staticCall", queue);
         assertThat(queue, is(Arrays.asList("foo before static method", "bar 
before static method", "on static method", "foo after static method", "bar 
after static method")));
     }
     
@@ -108,10 +120,41 @@ class AgentBuilderFactoryTest {
     void assertAdviceStaticMethodWhenExceptionThrown() {
         List<String> queue = new LinkedList<>();
         try {
-            TargetObjectFixture.staticCallWhenExceptionThrown(queue);
+            invokeStatic("staticCallWhenExceptionThrown", queue);
         } catch (final UnsupportedOperationException ignored) {
         }
         assertThat(queue, is(Arrays.asList("foo before static method", "bar 
before static method",
                 "foo throw static method exception", "bar throw static method 
exception", "foo after static method", "bar after static method")));
     }
+    
+    private void invokeConstructor(final List<String> queue) {
+        try {
+            targetClass.getConstructor(List.class).newInstance(queue);
+        } catch (final ReflectiveOperationException ex) {
+            throw new AssertionError("Failed to invoke constructor", ex);
+        }
+    }
+    
+    private void invokeInstance(final String methodName, final List<String> 
queue) {
+        try {
+            Object instance = 
targetClass.getConstructor(List.class).newInstance(new LinkedList<>());
+            targetClass.getMethod(methodName, List.class).invoke(instance, 
queue);
+        } catch (final ReflectiveOperationException ex) {
+            if (ex.getCause() instanceof UnsupportedOperationException) {
+                throw (UnsupportedOperationException) ex.getCause();
+            }
+            throw new AssertionError(String.format("Failed to invoke instance 
method %s", methodName), ex);
+        }
+    }
+    
+    private void invokeStatic(final String methodName, final List<String> 
queue) {
+        try {
+            targetClass.getMethod(methodName, List.class).invoke(null, queue);
+        } catch (final ReflectiveOperationException ex) {
+            if (ex.getCause() instanceof UnsupportedOperationException) {
+                throw (UnsupportedOperationException) ex.getCause();
+            }
+            throw new AssertionError(String.format("Failed to invoke static 
method %s", methodName), ex);
+        }
+    }
 }
diff --git 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/builder/interceptor/impl/MethodAdvisorBuilderInterceptorTest.java
 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/builder/interceptor/impl/MethodAdvisorBuilderInterceptorTest.java
new file mode 100644
index 00000000000..7041f76b7b2
--- /dev/null
+++ 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/builder/interceptor/impl/MethodAdvisorBuilderInterceptorTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.agent.core.builder.interceptor.impl;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.description.method.MethodList.Explicit;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.dynamic.DynamicType.Builder;
+import 
org.apache.shardingsphere.agent.core.advisor.config.AdvisorConfiguration;
+import org.apache.shardingsphere.agent.core.advisor.executor.AdviceExecutor;
+import 
org.apache.shardingsphere.agent.core.advisor.executor.AdviceExecutorFactory;
+import org.apache.shardingsphere.agent.core.advisor.executor.AdviceFactory;
+import 
org.apache.shardingsphere.agent.core.plugin.classloader.ClassLoaderContext;
+import org.apache.shardingsphere.fixture.targeted.TargetObjectFixture;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class MethodAdvisorBuilderInterceptorTest {
+    
+    @AfterEach
+    void resetCache() throws ReflectiveOperationException {
+        ((Map<?, ?>) 
Plugins.getMemberAccessor().get(AdviceFactory.class.getDeclaredField("CACHED_ADVICES"),
 null)).clear();
+        ((Map<?, ?>) 
Plugins.getMemberAccessor().get(ClassLoaderContext.class.getDeclaredField("AGENT_CLASS_LOADERS"),
 null)).clear();
+    }
+    
+    @Test
+    void assertInterceptWhenNoMatchedAdvice() throws 
ReflectiveOperationException {
+        AdvisorConfiguration advisorConfig = new 
AdvisorConfiguration(TargetObjectFixture.class.getName());
+        TypeDescription typeDescription = mock(TypeDescription.class);
+        when(typeDescription.getDeclaredMethods()).thenReturn(new Explicit<>(
+                Collections.singletonList(new 
MethodDescription.ForLoadedMethod(TargetObjectFixture.class.getMethod("call", 
List.class)))));
+        MethodAdvisorBuilderInterceptor interceptor = new 
MethodAdvisorBuilderInterceptor(
+                typeDescription, new ClassLoaderContext(new URLClassLoader(new 
URL[0], getClass().getClassLoader()), Collections.emptyList()), advisorConfig);
+        Builder<?> builder = mock(Builder.class);
+        assertThat(interceptor.intercept(builder), is(builder));
+    }
+    
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Test
+    void assertInterceptWhenAdviceMatched() throws 
ReflectiveOperationException {
+        TypeDescription typeDescription = mock(TypeDescription.class);
+        MethodDescription.InDefinedShape methodDescription = 
mock(MethodDescription.InDefinedShape.class);
+        when(typeDescription.getDeclaredMethods()).thenReturn(new 
Explicit<>(Collections.singletonList(methodDescription)));
+        MethodAdvisorBuilderInterceptor interceptor = new 
MethodAdvisorBuilderInterceptor(
+                typeDescription, new ClassLoaderContext(new URLClassLoader(new 
URL[0], getClass().getClassLoader()), Collections.emptyList()), new 
AdvisorConfiguration("ignored"));
+        AdviceExecutorFactory factory = mock(AdviceExecutorFactory.class);
+        AdviceExecutor adviceExecutor = mock(AdviceExecutor.class);
+        Builder intercepted = mock(Builder.class);
+        
when(factory.findMatchedAdviceExecutor(methodDescription)).thenReturn(Optional.of(adviceExecutor));
+        when(adviceExecutor.intercept(any(Builder.class), 
any(MethodDescription.class))).thenReturn(intercepted);
+        
Plugins.getMemberAccessor().set(MethodAdvisorBuilderInterceptor.class.getDeclaredField("adviceExecutorFactory"),
 interceptor, factory);
+        Builder<?> builder = mock(Builder.class);
+        assertThat(interceptor.intercept(builder), is(intercepted));
+    }
+    
+    @Test
+    void assertInterceptWhenAdviceInterceptThrows() throws 
ReflectiveOperationException {
+        TypeDescription typeDescription = mock(TypeDescription.class);
+        MethodDescription.InDefinedShape methodDescription = 
mock(MethodDescription.InDefinedShape.class);
+        when(typeDescription.getDeclaredMethods()).thenReturn(new 
Explicit<>(Collections.singletonList(methodDescription)));
+        MethodAdvisorBuilderInterceptor interceptor = new 
MethodAdvisorBuilderInterceptor(
+                typeDescription, new ClassLoaderContext(new URLClassLoader(new 
URL[0], getClass().getClassLoader()), Collections.emptyList()), new 
AdvisorConfiguration("ignored"));
+        AdviceExecutorFactory factory = mock(AdviceExecutorFactory.class);
+        AdviceExecutor adviceExecutor = mock(AdviceExecutor.class);
+        
when(factory.findMatchedAdviceExecutor(methodDescription)).thenReturn(Optional.of(adviceExecutor));
+        when(adviceExecutor.intercept(any(Builder.class), 
any(MethodDescription.class))).thenThrow(new IllegalStateException("error"));
+        
Plugins.getMemberAccessor().set(MethodAdvisorBuilderInterceptor.class.getDeclaredField("adviceExecutorFactory"),
 interceptor, factory);
+        Builder<?> builder = mock(Builder.class);
+        assertThat(interceptor.intercept(builder), is(builder));
+    }
+}

Reply via email to