JUnit5: How to assert several properties of an object with a single assert call?

With AssertJ, another option would be to use returns:

assertThat(product)
    .returns("Coat", from(Product::getName)),
    .returns(true, from(Product::getAvailable)),
    .returns(12, from(Product::getAmount)),
    .returns(new BigDecimal("88.0"), from(Product::getPrice));

A bit more verbose but I find it easier to read compared to extracting/contains.

Note that from is just an optional syntax sugar to improve readability.


Since 3.22.0, doesNotReturn is also available. This can be useful for non-null fields where the expected value is not known in advance.

assertThat(product)
    .returns("Coat", from(Product::getName)),
    .returns(true, from(Product::getAvailable)),
    .doesNotReturn(42, from(Product::getAmount)),
    .doesNotReturn(null, from(Product::getPrice));

With AssertJ the closest is :

assertThat(product).extracting("name", "available", "amount", "price")
                   .containsExactly("Coat", true, 12, new BigDecimal("88.0"));

But I don't like to reference field names with Strings because their validity as field names are checked only at the runtime (known issue of reflection) and that these Strings may also be incorrectly updated during refactoring operations that we perform from the IDE.

While a little more verbose, I prefer that :

assertThat(product).extracting(Product::getName, Product::getAvailable, 
                               Product::getAmount, Product::getPrice)
                   .containsExactly("Coat", true, 12, new BigDecimal("88.0"));

The advantage of AssertJ over Hamcrest that you quote is that that is really fluent : so in most of cases, you need a single import : import org.assertj.core.api.Assertions; and for collection assertions, sometimes that : org.assertj.core.groups.Tuple;

Here JUnit 5 or 4; it doesn't really matter since you will only use JUnit as a test runner for a very simple case and leave AssertJ to perform the assertions.

Or, alternatively, what is the best way of doing that in JUnit 5 universe.

JUnit 5 (as the 4th version) doesn't provide features for flexible and fluent assertions. So doing it with the best way of JUnit 5 is bound to produce much more boiler plate code : as many assertions as fields to assert or overriding equals()/hashCode() override that you want to avoid for fair reasons.