How to assert a specific field within an exception using `assertThatExceptionOfType()` in AssertJ?

How to assert a specific field within an exception using assertThatExceptionOfType() in AssertJ?

When testing exception handling in AssertJ using assertThatExceptionOfType(DataIntegrityViolationException.class), it’s possible to verify the exception type and cause. However, if the cause (like ConstraintViolationException) contains a custom field such as constraintName, how can you assert its value? Is there a built-in way in AssertJ to check fields of the thrown exception?

You know, having worked with AssertJ for quite some time, this is one of those patterns I end up using a lot. "<insert-exact-match-keyword>" Yes, you can assert a specific field inside the thrown exception using assertThatExceptionOfType(), the trick is to use satisfies() to dig into the exception object manually. That gives you full control:

assertThatExceptionOfType(DataIntegrityViolationException.class)
    .isThrownBy(() -> service.save(invalidEntity))
    .withCauseInstanceOf(ConstraintViolationException.class)
    .satisfies(ex -> {
        ConstraintViolationException cause =
            (ConstraintViolationException) ex.getCause();
        assertThat(cause.getConstraintName())
            .isEqualTo("EXPECTED_CONSTRAINT");
    });

I like this because you’re literally inside the exception and can assert anything you want — private fields, derived values, anything.

Totally agree with Archana, I’ve run into the same need many times while debugging constraints. "<insert-exact-match-keyword>" If you want a slightly cleaner or more declarative style, AssertJ’s extracting() is super handy. It keeps the chain fluent and readable, especially when you need to inspect multiple fields:

assertThatExceptionOfType(DataIntegrityViolationException.class)
    .isThrownBy(() -> service.save(invalidEntity))
    .withCauseInstanceOf(ConstraintViolationException.class)
    .extracting(Throwable::getCause)    // step into the cause
    .extracting("constraintName")        // pull a field by name
    .isEqualTo("EXPECTED_CONSTRAINT");

This works great when you just want to pluck out fields instead of writing a whole lambda block.

Yeah, both approaches above are spot-on. I’ve had to validate exception chains in pretty gnarly legacy code, so this comes up often. "<insert-exact-match-keyword>"

One more tip: if your exception stack is deep, you can chain .withCauseInstanceOf() multiple times to walk down the hierarchy. But honestly, satisfies() tends to be the safest when the structure isn’t predictable, especially if fields are private or exposed only through getters.

It gives you maximum control without losing readability, and you avoid brittle “extracting” chains when the exception model changes.