EventHandler { public void handleEvent(Object event) throws InvocationTargetException { if (!valid) { throw new IllegalStateException(toString() + " has been invalidated and can no longer handle events."); } try { method.invoke(target, event); } catch (IllegalAccessException e) { throw new AssertionError(e); } catch (InvocationTargetException e) { if (e.getCause() instanceof Error) { throw (Error) e.getCause(); } throw e; } } EventHandler(Object target, Method method); boolean isValid(); void invalidate(); void handleEvent(Object event); @Override String toString(); @Override int hashCode(); @Override boolean equals(Object obj);  }
@Test public void exceptionWrapping() throws NoSuchMethodException { Method method = getExceptionThrowingMethod(); EventHandler handler = new EventHandler(this, method); try { handler.handleEvent(new Object()); fail("Handlers whose methods throw must throw InvocationTargetException"); } catch (InvocationTargetException e) { assertTrue("Expected exception must be wrapped.", e.getCause() instanceof IntentionalException); } }
@Test public void errorPassthrough() throws InvocationTargetException, NoSuchMethodException { Method method = getErrorThrowingMethod(); EventHandler handler = new EventHandler(this, method); try { handler.handleEvent(new Object()); fail("Handlers whose methods throw Errors must rethrow them"); } catch (JudgmentError expected) { } }
@Test public void basicMethodCall() throws Exception { Method method = getRecordingMethod(); EventHandler handler = new EventHandler(this, method); handler.handleEvent(FIXTURE_ARGUMENT); assertTrue("Handler must call provided method.", methodCalled); assertSame("Handler argument must be *exactly* the provided object.", methodArgument, FIXTURE_ARGUMENT); }