### Question:
AbstractMaybeAsyncHandlerBridge implements AsyncHandler<Void> { @Override public final void onThrowable(Throwable t) { if (delegateTerminated.getAndSet(true)) { return; } Throwable error = t; try { delegate().onThrowable(t); } catch (final Throwable x) { error = new CompositeException(Arrays.asList(t, x)); } emitOnError(error); } protected  AbstractMaybeAsyncHandlerBridge(MaybeEmitter<T> emitter); @Override final State onBodyPartReceived(HttpResponseBodyPart content); @Override final State onStatusReceived(HttpResponseStatus status); @Override final State onHeadersReceived(HttpHeaders headers); @Override State onTrailingHeadersReceived(HttpHeaders headers); @Override final Void onCompleted(); @Override final void onThrowable(Throwable t); @Override void onHostnameResolutionAttempt(String name); @Override void onHostnameResolutionSuccess(String name, List<InetSocketAddress> addresses); @Override void onHostnameResolutionFailure(String name, Throwable cause); @Override void onTcpConnectAttempt(InetSocketAddress remoteAddress); @Override void onTcpConnectSuccess(InetSocketAddress remoteAddress, Channel connection); @Override void onTcpConnectFailure(InetSocketAddress remoteAddress, Throwable cause); @Override void onTlsHandshakeAttempt(); @Override void onTlsHandshakeSuccess(SSLSession sslSession); @Override void onTlsHandshakeFailure(Throwable cause); @Override void onConnectionPoolAttempt(); @Override void onConnectionPooled(Channel connection); @Override void onConnectionOffer(Channel connection); @Override void onRequestSend(NettyRequest request); @Override void onRetry();  }### Answer:
@Test public void wontCallOnErrorTwice() { InOrder inOrder = Mockito.inOrder(emitter); underTest.onThrowable(null); inOrder.verify(emitter).onError(null); underTest.onThrowable(new RuntimeException("unwanted")); inOrder.verify(emitter, never()).onError(any()); }
@Test public void wontCallOnErrorAfterDisposal() { given(emitter.isDisposed()).willReturn(true); underTest.onThrowable(new RuntimeException("ignored")); verify(emitter, never()).onError(any()); }
@Test public void handlesExceptionsWhileFailing() { final Throwable initial = new RuntimeException("mocked error for onThrowable()"); final Throwable followup = new RuntimeException("mocked error in delegate onThrowable()"); willThrow(followup).given(delegate).onThrowable(initial); underTest.onThrowable(initial); then(emitter).should().onError(throwable.capture()); final Throwable thrown = throwable.getValue(); assertThat(thrown, is(instanceOf(CompositeException.class))); assertThat(((CompositeException) thrown).getExceptions(), is(Arrays.asList(initial, followup))); }
@Test(dataProvider = "httpEvents") public void httpEventCallbacksCheckDisposal(Callable<AsyncHandler.State> httpEvent) throws Exception { given(emitter.isDisposed()).willReturn(true); final AsyncHandler.State firstState = httpEvent.call(); assertThat(firstState, is(State.ABORT)); then(delegate).should(only()).onThrowable(isA(DisposedException.class)); final AsyncHandler.State secondState = httpEvent.call(); assertThat(secondState, is(State.ABORT)); verifyNoMoreInteractions(delegate); }
@Test(dataProvider = "variousEvents") public void variousEventCallbacksCheckDisposal(Runnable event) { given(emitter.isDisposed()).willReturn(true); event.run(); then(delegate).should(only()).onThrowable(isA(DisposedException.class)); event.run(); verifyNoMoreInteractions(delegate); }