Search code examples
javajunitjunit5hamcrestassertj

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


I want to assert several properties of an object with a single assert call.

With JUnit 4 and Hamcrest I would have written something like this:

assertThat(product, allOf(
        hasProperty("name", is("Coat")),
        hasProperty("available", is(true)),
        hasProperty("amount", is(12)),
        hasProperty("price", is(new BigDecimal("88.0")))
));

Q: How to assert several properties in a single assert call using JUnit 5 and AssertJ? Or, alternatively, what is the best way of doing that in JUnit 5 universe.

Note: I can of course create an object with all needed properties and perform

assertThat(actualProduct, is(expectedProduct))

but that is not the point.


Solution

  • With AssertJ, another option would be to use returns:

    import static org.assertj.core.api.Assertions.from;
    
    assertThat(product)
        .returns("Coat", from(Product::getName))
        .returns(true, from(Product::getAvailable))
         //
         // or without 'from()'
         //
        .returns(12, Product::getAmount)
        .returns(new BigDecimal("88.0"), 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));