Как проверить в jUnit равенство объектов с двойными полями - PullRequest
0 голосов
/ 26 декабря 2018

Мы все знаем, как правильно проверять дробные числа в тестах (используя TOLERANCE):

class OxygenTankTest {
    static final double TOLERANCE = 0.001;

    @Test
    void testFilling() {
        OxygenTank tank = OxygenTank.withCapacity(100);
        tank.fill(5.8);
        tank.fill(5.6);
        Assertions.assertEquals(0.114, tank.getStatus(), TOLERANCE);
    }
}

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

Например: нужно тестировать Лето - который выполняет суммирование полей

public class Summer {
    public void setSum(Item itemTo, Item itemFrom) {
        itemTo.setDiameter(itemTo.getDiameter() + itemFrom.getDiameter());
        itemTo.setLength(itemTo.getLength() + itemFrom.getLength());
    }
}

public class Item {
    private Double diameter;
    private Double length;

    public Item(Double diameter, Double length) {
        this.diameter = diameter;
        this.length = length;
    }

    public Double getDiameter() {
        return diameter;
    }

    public void setDiameter(Double diameter) {
        this.diameter = diameter;
    }

    public Double getLength() {
        return length;
    }

    public void setLength(Double length) {
        this.length = length;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Item item = (Item) o;

        if (diameter != null ? !diameter.equals(item.diameter) : item.diameter != null) return false;
        return length != null ? length.equals(item.length) : item.length == null;
    }

    @Override
    public int hashCode() {
        int result = diameter != null ? diameter.hashCode() : 0;
        result = 31 * result + (length != null ? length.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Item{");
        sb.append("diameter=").append(diameter);
        sb.append(", length=").append(length);
        sb.append('}');
        return sb.toString();
    }
}

Как я пытаюсь написать тест:

public class SummerTest {

    @Test
    public void setSum() {
        Summer summer = new Summer();
        Item itemFrom = new Item(2.321, 1.111);
        Item itemTo = new Item(0.999, 0.999);

        summer.setSum(itemFrom, itemTo);

        // expected
        Item expectedItem = new Item(3.32, 2.11);

        assertThat(itemFrom, equalTo(expectedItem));
    }
}

Но это не такРабота!

java.lang.AssertionError: 
Expected: <Item{diameter=3.32, length=2.11}>
     but: was <Item{diameter=3.3200000000000003, length=2.11}>
Expected :<Item{diameter=3.32, length=2.11}>

Actual   :<Item{diameter=3.3200000000000003, length=2.11}>
 <Click to see difference>

Как правильно проверить на соответствие?

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Рассмотрите возможность изменения настроек теста, чтобы обеспечить точное сравнение с помощью Item::equals:

private static final double ITEM_FROM_DIAMETER = 2.321;
private static final double ITEM_FROM_LENGTH = 1.111;
private static final double ITEM_TO_DIAMETER = 0.999;
private static final double ITEM_TO_LENGTH = 0.999;

Item itemFrom = new Item(ITEM_FROM_DIAMETER, ITEM_FROM_LENGTH);
Item itemTo = new Item(ITEM_TO_DIAMETER, ITEM_TO_LENGTH);

Item expectedItem = new Item(ITEM_FROM_DIAMETER + ITEM_TO_DIAMETER, ITEM_FROM_LENGTH + ITEM_TO_LENGTH);

Кроме того, поскольку Item является изменяемым, было бы неплохо утверждать itemFromне был изменен.

0 голосов
/ 26 декабря 2018

Вы перезаписали метод equals, который проверяет точное равенство.Если у вас есть объекты, которые содержат значения с плавающей запятой (float, double), которые рассматриваются в вашей реализации equals, вы захотите сравнивать не сам объект, а значения внутри объекта:

assertEquals(expected.getDiameter(), itemFrom.getDiameter(), TOLERANCE);
assertEquals(expected.getLength(), itemFrom.getLength(), TOLERANCE);

Или еслиВы хотите получить фантазию, вы можете создать свой собственный Matcher, который входит в assertThat.

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