[英]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.