AssertJ: для Pojo, как проверить каждое вложенное свойство / поле в одном связанном предложении

Имея POJO, например:

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
}

О JUnit работе с AssertJ допустимо следующее, метод @Test проходит:

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();

Даже когда это работает, в некотором смысле многословен.

Я хочу знать, возможно ли переписать все вышеперечисленное одним предложением, проверяя каждое вложенное свойство / поле. Таким образом, я пробовал, например, следующее:

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

Но возникает следующее сообщение об ошибке:

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

Моя основная цель - обходной путь с isNotNull и isNull для каждого свойства / поля POJO

Альфа: благодаря предложению Joel теперь работает следующее:

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

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

Сверху (два блока) Если я попробую следующее (один блок):

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

Это не удается. Просто любопытно, можно ли применить один блок.


person Manuel Jordan    schedule 25.12.2017    source источник


Ответы (1)


Я думаю, что лучший способ - извлеките все свойства / поля и затем проверяет, не содержат ли они null.

Пример:

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

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

Обратите внимание, что вы также можете использовать лямбда-выражения для извлечения значений из тестируемого объекта.

assertThat(frodo).extracting(TolkienCharacter::getName,
                             character -> character.age,
                             character -> character.getRace().getName())
                 .containsExactly("Frodo", 33, "Hobbit");
person Joel Costigliola    schedule 26.12.2017
comment
Спасибо, пожалуйста, посмотрите, что добавлен раздел Альфа. Не уверен, что возможен один блок. - person Manuel Jordan; 26.12.2017
comment
Это не сработает, потому что после применения extracting вы в конечном итоге выполняете утверждения для коллекции значений, соответствующих извлеченным свойствам. Если вы снова используете extracting, он попытается извлечь свойства из каждого элемента предыдущей коллекции значений. - person Joel Costigliola; 26.12.2017
comment
что произойдет, если character.getRace() имеет значение null, не взорвется ли тестовый пример с помощью NullPointerException? - person Govinda Sakhare; 14.01.2021
comment
да, вы бы получили NPE - person Joel Costigliola; 14.01.2021