Сравните все свойства в двух объектах разных классов в модульном тесте - PullRequest
0 голосов
/ 25 июня 2019

У меня есть несколько объектов (из другого класса), скажем PersonType1 и PersonType2, и я пытаюсь сравнить поля в тестовом примере. Сценарий похож на:

jsonA -> PersonTypeA;
jsonB -> PersonTypeB;

и PersonTypeA.class, и PersonTypeB.class имеют одинаковые свойства, например, идентификатор, имя и т. Д.

Я пытаюсь утверждать, что значения равны следующим образом:

assertEquals(personA.getId(), personB.getId());

Я не могу использовать стандартные отражения, предоставляемые Mockito, поскольку классы не совпадают. Я не планирую писать кучу дополнительного кода для сравнения объектов. Нечто большее в линии:

Assert.assertTrue(new ReflectionEquals(expected, excludeFields).matches(actual)); //mockito

до

Assert.assertTrue(compareProperties(expected, excludeFields).matches(actual));

Редактировать 1: Это не повторяющийся вопрос Я пытаюсь сравнить 2 разных объекта разных классов , если они имеют одинаковое значение в свойствах с одинаковыми именами. Я могу написать код, но ищу некоторые существующие методы утилит, если они уже присутствуют в junit5, mockito, hamcrest и т. Д.

assertEquals(objA.getId(), objB.getId());
//like this there are 30 properties

также есть вложенные объекты, такие как список, набор строк. Сравнивать их вручную - слишком много боли

Редактировать 2: Может быть, это объяснит лучше

У меня нет контроля над POJO. Они принадлежат кому-то другому. Итак, по сути, если у меня есть 2 класса

class Cat{
  String id;
  String name;
  // 30 more properties
}

class Dog{
  String id;
  String name;
 // 30 more properties
}

Как сравнивать кошку и собаку с одинаковыми значениями в id, имени и т. Д. Поскольку существует так много свойств, которые я не хочу писать

assertEquals(cat.getId(), dog.getId());

Итак, есть ли какая-нибудь утилита для этого? Мы можем сделать наоборот, если у нас есть 2 объекта (разных классов), мы можем скопировать свойства, используя BeanUtils.copyProperies(o1, o2) в утилитах Spring и apache bean. Точно так же есть способ сравнить свойства?

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Есть много способов достижения цели, назовите несколько:

Вариант 1

Создайте свой собственный Matcher, и вы сможете использовать что-токак это:

assertThat(actual, MyMatchers.semanticallyEqualsTo(expected));

Опция 2

Создать собственный метод «CompareProperties (ожидаемый, фактический)» меньше стиля BDD, но все еще может работать

Вариант 3

Укажите метод преобразования:

class PersonTypeA {
   public PersonTypeB asTypeB() {
     ... if it has same properties, the conversion is trivial
     return new PersonTypeB   
   }
}

, а затем используйте этот метод в тесте, чтобы ожидаемый и фактический значения были одного типа, и вы можетеиспользуйте обычный assertEquals

Вариант 4

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

 class PersonTypeA {
    public JSONObject toJson() {...}
 }

 class PersonTypeB {
    public JSONObject toJson();
 }

Затем в тесте вы можете сравнить JSON с JSON.Поскольку это более сложно, чем простое сравнение строк (пары ключ / значение в JSON неупорядочены), вам может потребоваться библиотека сравнения JSON для тестов.Что-то вроде jsonassert , есть и другие.

Примечания: Опции 3 и 4 также могут быть реализованы «внешне» для PersonTypeA и PersonTypeB в некотором служебном классе.

Лично я бы выбрал первый вариант, особенно если вы увидите, что вы сталкиваетесь с этой проблемой во многих тестах, потому что в конце концов он позволяет написать самый чистый тест, а также немного лучше с точки зрения производительности, по крайней мере, чем вариант 4,нет необходимости возиться с преобразованиями JSON.

Но технически все опции здесь действительны

0 голосов
/ 01 июля 2019

Я не получил никакого решения, но выпишу то, что сделал.

Для сравнения объектов того же класса мы можем использовать Mockito ReflectionEquals, как показано ниже.Перейдите по ссылке для исходного ответа

assertTrue(new ReflectionEquals(deployments.get(0)).matches(returnedDeployments.get(0)));

https://stackoverflow.com/a/29793460/3497657

Я видел, потому что ReflectionEquals является внутренним классом, лучше использовать Hamcrest samePropertyValuesКак так:

assertThat(returnedDeployments.get(0), samePropertyValuesAs(deployments.get(0)));

Однако для объектов другого класса я ничего не нашел, поэтому мне пришлось написать Matcher самостоятельно

public class HasSameProperties<T> extends TypeSafeDiagnosingMatcher<T> {
  private ClassA obj1;

  public HasSameProperties(ClassA obj1) {
    this.obj1 = obj1;
  }

  @Override
  protected boolean matchesSafely(T item, Description mismatchDescription) {
     if (item instanceof ClassA)
       return matchClassA((ClassA) item);

     return null;
  }

  public static Matcher<ClassB> hasSameProperties(ClassA objA) {
    return new HasSameProperties(objA);
  }

  private boolean matchClassA(ClassB objB) {
    assertThat(objB.getId(), equalTo(objA.getId()));
    //other getters and setters
    return true;
  }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...