PluginClassImplementation { public Object tryGetAsPluginClass() { return instanceRef.get(); } PluginClassImplementation(
            ClassFinder type,
            Object delegateInstance);  PluginClassImplementation(
            ClassFinder type,
            Object delegateInstance,
            InvocationHandlerFactory exceptionalCases); private  PluginClassImplementation(
            ClassFinder type,
            InvocationHandler invocationHandler); Object tryGetAsPluginClass();  }
@Test public void testDelegateToInterface() { Runnable wrapped = mock(Runnable.class); PluginClassImplementation impl = new PluginClassImplementation(classFinder(Runnable.class), new MyRunnable(wrapped)); Runnable instance = (Runnable)impl.tryGetAsPluginClass(); verifyRunForwarded(instance, wrapped); }
@Test public void testDelegateToInterfaceWithException() throws Throwable { Runnable2 wrapped = mock(Runnable2.class); final InvocationHandler run2Handler = mock(InvocationHandler.class); InvocationHandlerFactory exceptionalCase = (Object proxy, Method method, Object[] args) -> { return "run2".equals(method.getName()) ? run2Handler : null; }; PluginClassImplementation impl = new PluginClassImplementation( classFinder(Runnable2.class), new MyRunnable(wrapped), exceptionalCase); Runnable2 instance = (Runnable2)impl.tryGetAsPluginClass(); verifyRunForwarded(instance, wrapped); verifyZeroInteractions(run2Handler); instance.run2(); verify(wrapped, never()).run2(); verify(run2Handler).invoke(same(instance), any(Method.class), any(Object[].class)); }