AssertJ: For a Pojo how to check each nested Property/Field in one chained sentence

Manuel Jordan picture Manuel Jordan · Dec 25, 2017 · Viewed 8.3k times · Source

Having a POJO such as:

public class ClientWebRequest {

    private URI uri;
    private HttpMethod httpMethod;

    private final Header header;
    private final Body body;


    public ClientWebRequest(){
        header = new Header();
        body = new Body();
    }

    //getters and setters
}

About JUnit working with AssertJ the following is valid, the @Test method pass:

assertThat(clientWebRequest).isNotNull();
assertThat(clientWebRequest.getHeader()).isNotNull();
assertThat(clientWebRequest.getHeader().getAccept()).isNotNull();
assertThat(clientWebRequest.getHeader().getAcceptLanguage()).isNull();
assertThat(clientWebRequest.getHeader().getContentType()).isNull();
assertThat(clientWebRequest.getBody()).isNotNull();
assertThat(clientWebRequest.getBody().getBody()).isNull();

Even when it works, is verbose in some way.

I want to know if is possible rewrite all the above in just one sentence, checking each nested property/field. Thus I have tried for example the following:

assertThat(clientWebRequest.getHeader()).isNotNull()
        .hasFieldOrProperty("accept").isNotNull()
        .hasFieldOrProperty("acceptLanguage").isNull();

But fails with the following error message:

org.junit.ComparisonFailure: expected:<null> 
but was:<Header [accept=[application/json;charset=UTF-8], acceptLanguage=null, contentType=null]>
        at

My main goal is workaround with isNotNull and isNull for each property/field of the POJO

Alpha: Thanks to Joel's suggestion the following works now:

assertThat(clientWebRequest).isNotNull()
                            .extracting("header.accept")
                            .doesNotContainNull();

assertThat(clientWebRequest).isNotNull()
        .extracting("header.acceptLanguage", "header.contentType")
       .containsNull();

From above (two blocks) If I try the following (one block):

assertThat(clientWebRequest).isNotNull()
                            .extracting("header.accept")
                            .doesNotContainNull();
       .extracting("header.acceptLanguage", "header.contentType")
       .containsNull();

It fails. Just curious if is possible apply one block.

Answer

Joel Costigliola picture Joel Costigliola · Dec 26, 2017

I think the best way is to extract all the properties/fields and then checks it does not contain null.

Example:

TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);

// support nested properties: 
assertThat(frodo).extracting("name", "age", "race.name")
                 .doesNotContainNull()
                 .containsExactly("Frodo", 33, "Hobbit");

Note that you can also use lambdas to extract values from the object under test.

assertThat(frodo).extracting(TolkienCharacter::getName,
                             character -> character.age,
                             character -> character.getRace().getName())
                 .containsExactly("Frodo", 33, "Hobbit");