RefreshableProxyInvocationHandler extends AbstractInvocationHandler { public static <R, T> RefreshableProxyInvocationHandler<R, T> create( Refreshable<R> refreshable, Function<R, T> delegateSupplier) { return new RefreshableProxyInvocationHandler<>(refreshable, delegateSupplier); } private  RefreshableProxyInvocationHandler(Refreshable<R> refreshable, Function<R, T> delegateSupplier); static RefreshableProxyInvocationHandler<R, T> create(
            Refreshable<R> refreshable, Function<R, T> delegateSupplier);  }
@Test public void testUnwrapsInvocationTargetExceptions() { Callable throwingCallable = () -> { throw new IllegalStateException("Whoops"); }; Refreshable<Callable> refreshable = Refreshable.of(throwingCallable); RefreshableProxyInvocationHandler<Callable, Callable> handler = RefreshableProxyInvocationHandler.create(refreshable, _tec -> throwingCallable); Callable proxy = Reflection.newProxy(Callable.class, handler); assertThatThrownBy(proxy::call) .isInstanceOf(IllegalStateException.class) .hasMessage("Whoops"); }
@Test public void testCannotConstructProxyWhenInitialRefreshableIsEmpty() throws Exception { Refreshable<Object> refreshable = Refreshable.empty(); try { RefreshableProxyInvocationHandler.create(refreshable, supplier); failBecauseExceptionWasNotThrown(IllegalArgumentException.class); } catch (IllegalArgumentException e) { assertThat(e) .hasMessage("Cannot construct RefreshableProxyInvocationHandler with empty initial refreshable"); } }
@Test public void testUsesInitialDelegateAndUpdatesDelegatesWhenRefreshableChanges() throws Exception { Object object1 = new Object(); Object object2 = new Object(); when(supplier.apply(object1)).thenReturn(delegate1); Refreshable<Object> refreshable = Refreshable.of(object1); RefreshableProxyInvocationHandler<Object, Callable> handler = RefreshableProxyInvocationHandler.create(refreshable, supplier); verify(supplier).apply(object1); Callable proxy = Reflection.newProxy(Callable.class, handler); proxy.call(); verify(delegate1).call(); Mockito.verifyNoMoreInteractions(delegate1, delegate2, supplier); proxy.call(); verify(delegate1, times(2)).call(); Mockito.verifyNoMoreInteractions(delegate1, delegate2, supplier); refreshable.set(object2); when(supplier.apply(object2)).thenReturn(delegate2); proxy.call(); verify(delegate2).call(); verify(supplier).apply(object2); Mockito.verifyNoMoreInteractions(delegate1, delegate2, supplier); proxy.call(); verify(delegate2, times(2)).call(); Mockito.verifyNoMoreInteractions(delegate1, delegate2, supplier); }