@SuppressWarnings("unchecked")
    public static <T extends Exception> T assertFutureThrows(final Class<T> expectedType,
            final Future<?> future, final int timeout, final TimeUnit timeoutUnit) {
        final Throwable cause =
                assertThrows(ExecutionException.class, () -> future.get(timeout, timeoutUnit)).getCause();
        final Class<? extends Throwable> causeClass = cause.getClass();
        assertTrue(expectedType.isAssignableFrom(causeClass), "The cause was of type: " + causeClass.getName()
                + ", but it was expected to be a subclass of " + expectedType.getName());
        return (T) cause;
    }
Asserts that the given {@link Future} fails with an {@link ExecutionException} caused by the given exception
type.

@param <T> The type of the causing exception.
@param expectedType The expected type of the causing exception.
@param future The future expected to throw.
@param timeout The maximum time to wait for the result.
@param timeoutUnit The time unit of the {@code timeout} argument.
@return The causing exception.
tests/src/test/java/net/devh/boot/grpc/test/util/FutureAssertions.java