public static void assertThrowsCause(String message,
                                       Class<? extends Exception> expected,
                                       String containedInMessage,
                                       Runnable runnable) {
    Assertions.assertThatThrownBy(runnable::run)
        .withFailMessage(message)
        .getCause()
        .isInstanceOf(expected)
        .hasMessageContaining(containedInMessage);
  }
A convenience method to assert the cause of thrown exception.
@param message A String message to describe this assertion
@param expected An Exception class that the cause of the Runnable should throw
@param containedInMessage A String that should be contained by the cause of the thrown
                          exception's message
@param runnable A Runnable that is expected to throw the runtime exception
iceberg/iceberg-catalog/src/test/java/org/apache/iceberg/AssertHelpers.java