简体   繁体   English

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

[英]How to check in jUnit the equality of objects with double fields

We all know how to correctly check for fractional numbers in tests (using TOLERANCE): 我们都知道如何在测试中正确检查分数(使用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);
    }
}

But my question is how to check if we need to check not the individual values - but whole objects. 但是我的问题是如何检查我们是否需要检查的不是单个值,而是整个对象。

For example: Need to test Summer - which performs the summation of fields 例如:需要测试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();
    }
}

How i try to write a test: 我如何尝试编写测试:

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));
    }
}

But it does not work! 但这不起作用!

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>

How to properly check for compliance? 如何正确检查合规性?

You overwrote the equals method that checks for exact equality. 您重写了检查完全相等的equals方法。 If you have objects that contain floating point values (float, double) that are considered in your equals implementation, you will want to not compare the object itself, but the values within the object: 如果您的对象包含在equals实现中考虑的浮点值(float,double),则不希望比较对象本身,而是比较对象内的值:

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

Or if you want to get fancy you can create your own Matcher that goes into the assertThat . 或者,如果您想花哨的话,可以创建自己的Matcher ,将其放入assertThat

Consider changing the set up of the test to allow for exact comparisons via Item::equals : 考虑更改测试的设置,以允许通过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);

Also, since Item is mutable, it would be a good idea to assert itemFrom was not changed. 另外,由于Item是可变的,因此断言itemFrom是个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM