Как я могу сравнить POJO по своим полям

Я в основном ищу рамки модульного тестирования, которые я могу использовать для сравнения POJO, которые не переопределяют методы equals и hascode. Я посмотрел на JUnit, Test NG и Mockito, но они, похоже, не решают эту цель.

Например, рассмотрите следующий код:

public class CarBean { 

    private String brand;
    private String color;

    public CarBean (){
    }

    public CarBean (String brand, String color){
        this.brand= brand;
        this.color= color;
    }

    /**
     * @return the brand
     */
    public String getBrand() {
        return brand;
    }

    /**
     * @param the brand to set
     */
    public void setBrand(String brand) {
        this.brand= brand;
    }

    /**
     * @return the color
     */
    public String getColor() {
        return color;
    }

    /**
     * @param the color to set
     */
    public void setColor(String color) {
        this.color= color;
    }
}

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

CarBean car1 = new CarBean("Ford","Black");
CarBean car2 = new CarBean("Ford","Black");

Оба объекта имеют одинаковые значения параметров. Но когда вы сравниваете это с помощью equals, он возвращает false:

car1.equals(car2); // This returns false

Теперь мне нужно unit test метод, возвращающий объект CarBean. В этом случае мне нужно было бы либо сравнить атрибуты carbean по одному, либо мне нужно было бы реализовать методы equals() и hashcode().

Итак, мой вопрос: существует ли уже модульная система тестирования, которая может справиться с этим?

Ответ 1

Кажется, что Unitilies решает эту задачу для меня. Следующие API-интерфейсы могут объективно сравнивать объекты. Он может сравниться, даже если атрибуты POJO сами определяются пользователем POJO:

import static org.unitils.reflectionassert.ReflectionAssert.*;

// Exact field-by-field comparison
assertReflectionEquals(new Person("John", "Doe", new Address("New street", 5, "Brussels")), 
                                 new Person("John", "Doe", new Address("New street", 5, "Brussels"));

// Ignore Null / 0 values in the expected object
assertReflectionEquals(new Person("John", null, new Address("New street", 0, null)),
                                 new Person("John", "Doe", new Address("New street", 5, "Brussels"), 
                                 ReflectionComparatorMode.IGNORE_DEFAULTS); 

// Ignore collection order
assertReflectionEquals(Arrays.asList(new Person("John"), new Person("Jane")),
                                 new Person[] {new Person("Jane"), new Person("John")}, 
                                 ReflectionComparatorMode.LENIENT_ORDER);

// Ignore null/0 values + collection order
assertLenientEquals(Arrays.asList(new Person("John"), null),
                                 new Person[] {new Person("Jane", "Doe"), new Person("John", "Doe")});

// Check only the firstName property 
assertPropertyLenientEquals("firstName", Arrays.asList("John", "Jane"),
                                 new Person[] {new Person("Jane", "Doe"), new Person("John", "Doe")});

Дополнительная информация в Unitils Cookbook

Ответ 2

Этот тип отражения встроен в Hamcrest как SamePropertyValuesAs, который сравнивает свойства bean-name (getFoo, isBar) вместо поля, которые, вероятно, будут их использовать. Поддержка Core Hamcrest встроена в JUnit, поэтому вам просто нужно добавить библиотеку Hamcrest, которая включает в себя SamePropertyValuesAs.

assertThat(car1, samePropertyValuesAs(car2));

Ответ 3

Переопределите метод toString() в вашем классе pojo, как показано ниже

@Override
public String toString() {
    return "brand: " + this.brand + ",color: " + this.color;
}


car1.toString().equals(car2.toString()); //It will return true if both objects has same values

Если у вас большой номер параметра, я предложу вам использовать приведенный ниже код

public static boolean comparePOJO(Object obj1, Object obj2) {
    return new Gson().toJson(obj1).equals(new Gson().toJson(obj2));
}
comparePOJO(car1,car2); //It will return true

Ответ 4

Так как это, вероятно, будет реализовано с использованием рефлекса "отражение равно", это разумный термин поиска, и, действительно, Google находит:

http://www.unitils.org/tutorial-reflectionassert.html

Ответ 5

Ничто не мешает вам написать собственное сравнение

Использование JUnit:

напишите статический метод, который принимает 2 объекта и делает нужные вам утверждения:

public static void sameBrandAndColor(Car expected, Car actual){
     assertEquals(expected.getBrand(), actual.getBrand());
     assertEquals(expected.getColor(), actual.getColor());
}

Затем в ваших тестах просто вызовите ваш метод сравнения.

@Test
public void test(){
    ...
    sameBrandAndColor(car1, car2);
}