package net.bytebuddy.implementation.auxiliary; import net.bytebuddy.test.utility.CallTraceable; import net.bytebuddy.test.utility.ObjectPropertyAssertion; import org.junit.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Type; import java.util.concurrent.Callable; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; public class MethodCallProxyTest extends AbstractMethodCallProxyTest { private static final long LONG_VALUE = 42L; private static final String String_VALUE = "BAR"; private static final int INT_VALUE = 21; private static final boolean BOOLEAN_VALUE = true; @Test public void testNoParameterMethod() throws Exception { Class<?> auxiliaryType = proxyOnlyDeclaredMethodOf(NoParameterMethod.class); Constructor<?> constructor = auxiliaryType.getDeclaredConstructor(NoParameterMethod.class); constructor.setAccessible(true); NoParameterMethod runnableProxied = new NoParameterMethod(); ((Runnable) constructor.newInstance(runnableProxied)).run(); runnableProxied.assertOnlyCall(FOO, runnableProxied); NoParameterMethod callableProxied = new NoParameterMethod(); assertThat(((Callable<?>) constructor.newInstance(callableProxied)).call(), nullValue()); callableProxied.assertOnlyCall(FOO, callableProxied); } @Test public void testStaticMethod() throws Exception { Class<?> auxiliaryType = proxyOnlyDeclaredMethodOf(StaticMethod.class); Constructor<?> constructor = auxiliaryType.getDeclaredConstructor(); constructor.setAccessible(true); ((Runnable) constructor.newInstance()).run(); StaticMethod.CALL_TRACEABLE.assertOnlyCall(FOO); StaticMethod.CALL_TRACEABLE.reset(); assertThat(((Callable<?>) constructor.newInstance()).call(), nullValue()); StaticMethod.CALL_TRACEABLE.assertOnlyCall(FOO); StaticMethod.CALL_TRACEABLE.reset(); } @Test public void testMultipleParameterMethod() throws Exception { Class<?> auxiliaryType = proxyOnlyDeclaredMethodOf(MultipleParameterMethod.class); Constructor<?> constructor = auxiliaryType.getDeclaredConstructor(MultipleParameterMethod.class, long.class, String.class, int.class, boolean.class); constructor.setAccessible(true); MultipleParameterMethod runnableProxied = new MultipleParameterMethod(); Object[] runnableArguments = new Object[]{runnableProxied, LONG_VALUE, String_VALUE, INT_VALUE, BOOLEAN_VALUE}; ((Runnable) constructor.newInstance(runnableArguments)).run(); runnableProxied.assertOnlyCall(FOO, runnableArguments); MultipleParameterMethod callableProxied = new MultipleParameterMethod(); Object[] callableArguments = new Object[]{callableProxied, LONG_VALUE, String_VALUE, INT_VALUE, BOOLEAN_VALUE}; assertThat(((Callable<?>) constructor.newInstance(callableArguments)).call(), nullValue()); callableProxied.assertOnlyCall(FOO, callableArguments); } @Test public void testNonGenericParameter() throws Exception { Class<?> auxiliaryType = proxyOnlyDeclaredMethodOf(GenericType.class); assertThat(auxiliaryType.getTypeParameters().length, is(0)); assertThat(auxiliaryType.getDeclaredMethod("call").getGenericReturnType(), is((Type) Object.class)); assertThat(auxiliaryType.getDeclaredFields()[1].getGenericType(), is((Type) Object.class)); assertThat(auxiliaryType.getDeclaredFields()[2].getGenericType(), is((Type) Number.class)); } @Test public void testObjectProperties() throws Exception { ObjectPropertyAssertion.of(MethodCallProxy.class).apply(); ObjectPropertyAssertion.of(MethodCallProxy.AssignableSignatureCall.class).apply(); ObjectPropertyAssertion.of(MethodCallProxy.ConstructorCall.class).apply(); ObjectPropertyAssertion.of(MethodCallProxy.MethodCall.class).apply(); ObjectPropertyAssertion.of(MethodCallProxy.MethodCall.Appender.class).skipSynthetic().apply(); } @SuppressWarnings("unused") public static class NoParameterMethod extends CallTraceable { public void foo() { register(FOO, this); } } @SuppressWarnings("unused") public static class StaticMethod extends CallTraceable { public static final CallTraceable CALL_TRACEABLE = new CallTraceable(); public static void foo() { CALL_TRACEABLE.register(FOO); } } @SuppressWarnings("unused") public static class MultipleParameterMethod extends CallTraceable { public void foo(long l, String s, int i, boolean b) { register(FOO, this, l, s, i, b); } } @SuppressWarnings("unused") public static class GenericType<T, S extends Number> { T foo(T t, S s) { return t; } } }