Search code examples
javajunit5assertj

AssertJ: How to return the actual exception when using method assertThatThrownBy


I am migrating from JUnit 5 and Hamcrest Assertions to AssertJ and I can't figure out the right method for extracting the actual exception from the executable. Here is a JUnit/Hamcrest example:

var result = assertThrows(MyException.class, () -> this.objectUnderTest.someMethod(param1, param2, param3));
assertThat(result.getError().getErrorCode(), equalTo(someValue));
assertThat(result.getError().getDescription(), equalTo("someString"));

What I would like to have is smth. like (AssertJ)

var result = assertThatThrownBy(() -> this.objectUnderTest.someMethod(param1, param2, param3))
 .isInstanceOf(MyException.class);
assertThat(result.getError().getErrorCode(), equalTo(someValue));
assertThat(result.getError().getDescription(), equalTo("someString"));

But as of the AssertJ version 3.21.0 the assertThatThrownBy method gives me an instance of AbstractThrowableAssert<?, ? extends Throwable> class and I can't find any method which would give me then the MyException instance. So for now I ended up using another method and casting manually to MyException:

Throwable throwable = Assertions.catchThrowable(() -> this.objectUnderTest.doFilterInternal(param1, param2, param3));
MyException exception = (MyException) throwable;
assertThat(exception.getError().getErrorCode(), equalTo(someValue));
assertThat(exception.getError().getDescription(), equalTo("someString"));

Solution

  • AssertJ offers two styles for checking custom exceptions:

    Keeping the style of your example, you can write the following with catchThrowable:

    Throwable throwable = catchThrowable(() -> this.objectUnderTest.someMethod(param1, param2, param3));
    
    assertThat(throwable)
      .asInstanceOf(InstanceOfAssertFactories.throwable(MyException.class))
      .extracting(MyException::getError)
      .returns(1, from(Error::getErrorCode))
      .returns("something", from(Error::getDescription));
    

    or, with catchThrowableOfType:

    MyException exception = catchThrowableOfType(() -> this.objectUnderTest.someMethod(param1, param2, param3), MyException.class);
    
    assertThat(exception)
      .extracting(MyException::getError)
      .returns(1, from(Error::getErrorCode))
      .returns("something", from(Error::getDescription));