我们都知道如何在测试中正确检查分数(使用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>
如何正确检查合规性?
答案 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
未被更改是一个好主意。