### Question:
AnnotationProxyFactory { public static <T extends Annotation> T getAnnotationProxy(Annotation customAnnotation, Class<T> referenceAnnotation) { InvocationHandler handler = new AnnotationInvocationHandler(customAnnotation); return (T) Proxy.newProxyInstance(referenceAnnotation.getClassLoader(), new Class[] {referenceAnnotation}, handler); } private  AnnotationProxyFactory(); static T getAnnotationProxy(Annotation customAnnotation, Class<T> referenceAnnotation);  }### Answer:
@Test(expected=UnsupportedOperationException.class) public void NoDefaultValueInReferenceAnnotationAndNoImplementationInCustomThrowsException_Test() { CustomAnnotation customAnnotation = UsingCustomAnnotation.class.getAnnotation(CustomAnnotation.class); ReferenceAnnotation annotationProxy = AnnotationProxyFactory.getAnnotationProxy(customAnnotation, ReferenceAnnotation.class); annotationProxy.things(); }
@Test public void NoImplementationInCustomFallsBackToReferenceImplementation_Test() { CustomAnnotation customAnnotation = UsingCustomAnnotation.class.getAnnotation(CustomAnnotation.class); ReferenceAnnotation annotationProxy = AnnotationProxyFactory.getAnnotationProxy(customAnnotation, ReferenceAnnotation.class); assertEquals("hello",annotationProxy.version()); }
@Test public void IfMethodExistsInCustomAnnotationRedirectsToIt_Test() { CustomAnnotation customAnnotation = UsingCustomAnnotation.class.getAnnotation(CustomAnnotation.class); ReferenceAnnotation annotationProxy = AnnotationProxyFactory.getAnnotationProxy(customAnnotation, ReferenceAnnotation.class); assertEquals(true,annotationProxy.deprecated()); }
@Test public void IfMethodExistsInCustomAnnotationButReturnTypeIsDifferentFallsBackToReferenceImplementation_Test() { CustomAnnotation customAnnotation = UsingCustomAnnotation.class.getAnnotation(CustomAnnotation.class); ReferenceAnnotation annotationProxy = AnnotationProxyFactory.getAnnotationProxy(customAnnotation, ReferenceAnnotation.class); assertEquals(5,annotationProxy.differentReturnType()); }
@Test public void DifferentReturnTypesFromDifferentMethods_Test() { CustomAnnotation customAnnotation = UsingCustomAnnotation.class.getAnnotation(CustomAnnotation.class); ReferenceAnnotation annotationProxy = AnnotationProxyFactory.getAnnotationProxy(customAnnotation, ReferenceAnnotation.class); assertEquals(Integer.class,annotationProxy.aClass()); assertEquals(ExampleEnum.TWO ,annotationProxy.anEnum()); assertEquals(customAnnotation.anAnnotation(),annotationProxy.anAnnotation()); }