Сравните 2 объекта, игнорируя нулевые значения - PullRequest
2 голосов
/ 07 мая 2020

В проекте используются TestNg, Java11, Spring test

Я пишу тесты testNG для API У меня есть объект java с такой структурой:

class Object1
    private Object2 o2;
    private List<Object3> o3;

Где Object2 состоит не только из примитивных атрибутов.

Я хотел бы проверить, равны ли 2 Object1 этим правилам:

  • если фактическое o2 равно нулю, не 'не терпит неудачу, даже если другой o2 не
  • , если фактический o3 является нулем или пустым, не терпит неудачу, даже если другой o3 не
  • если фактический o3 не является ни нулевым, ни пустым, сравнивайте только ненулевые Object3 поля

Подводя итог, я хотел бы утверждать, что 2 объекта одинаковы, рекурсивно игнорируя нулевые поля.

Я мог бы это сделать

assertThat(actual).usingRecursiveComparison().ignoringActualNullFields().isEqualTo(other);

, но рекурсивные пустые поля не игнорируются.

Как я могу это исправить?

Ответы [ 3 ]

0 голосов
/ 09 мая 2020

У меня работал следующий код:

public class SocialLink {
    private String platform;
    private String link;
}

SocialLink obj1 = new SocialLink("Facebook", null);
SocialLink obj2 = new SocialLink("Facebook", null);

assertThat(obj1).isEqualToIgnoringNullFields(obj2);
0 голосов
/ 04 июня 2020

Наконец-то я создал свои собственные утверждения вроде этого:

import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.Assertions;

import java.util.List;
import java.util.stream.Collectors;

public class Object1Assert extends AbstractAssert<Object1Assert, Object1> {

    public Object1Assert isEqualTo(Object1 other) {

        // specially for null
        if(actual == other) {return this;}

        if(actual.getObject2() != null) {
            Assertions.assertThat(other.getObject2()).isEqualToIgnoringNullFields(actual.getObject2());
        }

        if(actual.getObject3() != null) {
            for(Object3 object3 : actual.getObject3()) {
                my.package.Assertions.assertThat(object3).isIn(other.getObject3());
            }
        }
        // return the current assertion for method chaining
        return this;
    }

    public Object1Assert(Object1 actual) {
        super(actual, Object1Assert.class);
    }

    public static Object1Assert assertThat(Object1 actual) {
        return new Object1Assert(actual);
    }

}

public class Assertions {

    public static Object3Assert assertThat(Object3 actual) {
        return new Object3Assert(actual);
    }
}
public class Object3Assert extends AbstractAssert<Object3Assert, Object3> {

    public Object3Assert isIn(List<Object3> others) {
        List<String> otherStringIds = others.stream().map(Object3::getStringId).collect(Collectors.toList());
        Assertions.assertThat(otherStringIds).isNotEmpty();
        Assertions.assertThat(actual.getStringId()).isIn(otherStringIds);
        for (Object3 otherObject3 : others) {
            if(actual.getStringId().equalsIgnoreCase(otherObject3.getStringId())) {
                Assertions.assertThat(otherObject3).usingComparatorForType(Comparators.bigDecimalComparator, BigDecimal.class).isEqualToIgnoringNullFields(actual);
            }
        }
        // return the current assertion for method chaining
        return this;
    }

    public Object3Assert(Object3 actual) {
        super(actual, Object3Assert.class);
    }

    public static Object3Assert assertThat(Object3 actual) {
        return new Object3Assert(actual);
    }

}

Я создал этот класс для каждого типа, который мне нужен в этом руководстве https://www.baeldung.com/assertj-custom-assertion

0 голосов
/ 08 мая 2020

Вы также можете игнорировать ожидаемые пустые поля. .

Можете ли вы также предоставить простой тест для воспроизведения проблемы? Не стесняйтесь поднимать вопрос в https://github.com/joel-costigliola/assertj-core/issues

...