如何在jUnit中检查具有双精度字段的对象相等性



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

如何正确检查合规性?

您覆盖了检查完全相等性的equals方法。如果您的对象包含 equals 实现中考虑的浮点值(浮点数、双精度值),则您不希望比较对象本身,而是比较对象中的值:

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

或者,如果您想花哨,可以创建自己的Matcher进入assertThat

考虑更改测试的设置,以便通过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未更改。

相关内容

  • 没有找到相关文章

最新更新