如何在jUnit中检查具有双字段的对象是否相等

时间:2018-12-26 15:01:05

标签: java junit mockito

我们都知道如何在测试中正确检查分数(使用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);
    }
}

但是我的问题是如何检查我们是否需要检查的不是单个值-而是整个对象。

例如: 需要测试Summer-执行字段求和

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 :(得分:3)

您重写了equals方法,该方法检查确切的相等性。如果您的对象包含在equals实现中考虑的浮点值(float,double),则不希望比较对象本身,而是比较对象内的值:

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

或者,如果您想花哨的话,可以创建自己的Matcher,并将其放入assertThat

答案 1 :(得分:1)

考虑更改测试设置,以允许通过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未被更改是一个好主意。