package net.bytebuddy.implementation.bind.annotation; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.implementation.bind.MethodDelegationBinder; import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.test.utility.ObjectPropertyAssertion; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.*; public class SuperBinderTest extends AbstractAnnotationBinderTest<Super> { @Mock private TypeDescription targetType; @Mock private TypeDescription.Generic genericTargetType; @Mock private Super.Instantiation instantiation; public SuperBinderTest() { super(Super.class); } @Override @Before public void setUp() throws Exception { super.setUp(); when(target.getType()).thenReturn(genericTargetType); when(genericTargetType.asErasure()).thenReturn(targetType); when(annotation.strategy()).thenReturn(instantiation); when(instantiation.proxyFor(targetType, implementationTarget, annotationDescription)).thenReturn(stackManipulation); when(annotation.constructorParameters()).thenReturn(new Class<?>[0]); when(targetType.asErasure()).thenReturn(targetType); } @Override protected TargetMethodAnnotationDrivenBinder.ParameterBinder<Super> getSimpleBinder() { return Super.Binder.INSTANCE; } @Test public void testAssignableBinding() throws Exception { doReturn(void.class).when(annotation).proxyType(); when(stackManipulation.isValid()).thenReturn(true); when(instrumentedType.isAssignableTo(targetType)).thenReturn(true); MethodDelegationBinder.ParameterBinding<?> parameterBinding = Super.Binder.INSTANCE .bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); assertThat(parameterBinding.isValid(), is(true)); verify(instantiation).proxyFor(targetType, implementationTarget, annotationDescription); } @Test public void testIllegalBindingForNonAssignableType() throws Exception { doReturn(void.class).when(annotation).proxyType(); MethodDelegationBinder.ParameterBinding<?> parameterBinding = Super.Binder.INSTANCE .bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); assertThat(parameterBinding.isValid(), is(false)); } @Test public void testIllegalBindingStaticMethod() throws Exception { doReturn(void.class).when(annotation).proxyType(); when(source.isStatic()).thenReturn(true); MethodDelegationBinder.ParameterBinding<?> parameterBinding = Super.Binder.INSTANCE .bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); assertThat(parameterBinding.isValid(), is(false)); } @Test(expected = IllegalStateException.class) public void testPrimitiveParameterType() throws Exception { when(genericTargetType.isPrimitive()).thenReturn(true); Super.Binder.INSTANCE.bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); } @Test(expected = IllegalStateException.class) public void testArrayParameterType() throws Exception { when(genericTargetType.isArray()).thenReturn(true); Super.Binder.INSTANCE.bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); } @Test(expected = IllegalStateException.class) public void testPrimitiveProxyType() throws Exception { doReturn(int.class).when(annotation).proxyType(); Super.Binder.INSTANCE.bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); } @Test(expected = IllegalStateException.class) public void testArrayProxyType() throws Exception { doReturn(Object[].class).when(annotation).proxyType(); Super.Binder.INSTANCE.bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); } @Test(expected = IllegalStateException.class) public void testNonAssignableType() throws Exception { doReturn(Void.class).when(annotation).proxyType(); Super.Binder.INSTANCE.bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); } @Test(expected = IllegalStateException.class) public void testFinalProxyType() throws Exception { doReturn(void.class).when(annotation).proxyType(); when(targetType.isFinal()).thenReturn(true); Super.Binder.INSTANCE.bind(annotationDescription, source, target, implementationTarget, assigner, Assigner.Typing.STATIC); } @Test public void testObjectProperties() throws Exception { ObjectPropertyAssertion.of(Super.Binder.class).apply(); ObjectPropertyAssertion.of(Super.Instantiation.class).apply(); ObjectPropertyAssertion.of(Super.Binder.TypeLocator.ForInstrumentedType.class).apply(); ObjectPropertyAssertion.of(Super.Binder.TypeLocator.ForParameterType.class).apply(); ObjectPropertyAssertion.of(Super.Binder.TypeLocator.ForType.class).apply(); } }