@Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if ("equals".equals(method.getName())) {
      try {
        Object otherHandler =
            args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
        return equals(otherHandler);
      } catch (IllegalArgumentException e) {
        return false;
      }
    } else if ("hashCode".equals(method.getName())) {
      return hashCode();
    } else if ("toString".equals(method.getName())) {
      return toString();
    } else if (!dispatch.containsKey(method)) {
      throw new UnsupportedOperationException(
          String.format("Method \"%s\" should not be called", method.getName()));
    }
    return this.invoke(method, this.dispatch.get(method), args);
  }
@Test
  void invokeFailureRxJava() throws Throwable {
    given(this.methodHandler.invoke(any())).willThrow(new IOException("Could Not Decode"));
    RxJavaInvocationHandler handler =
        new RxJavaInvocationHandler(this.target,
            Collections.singletonMap(this.method, this.methodHandler),
            io.reactivex.schedulers.Schedulers.trampoline());

    Object result = handler.invoke(this.method, this.methodHandler, new Object[] {});
    assertThat(result).isInstanceOf(Flowable.class);
    verifyNoInteractions(this.methodHandler);

    /* subscribe and execute the method */
    StepVerifier.create((Flowable) result)
        .expectError(IOException.class)
        .verify();
    verify(this.methodHandler, times(1)).invoke(any());
  }