Answers:
Epsilon是两个数字可乘以的值。因此只要Math.abs(expected - actual) < epsilon
<=
不是<
。
doubleIsDifferent
(用于比较双精度值)并返回Math.abs(d1 - d2) > delta
。因此,如果d1和d2之间的差大于delta,则意味着值不同并且将返回true。如果认为值相等,它将返回false。该方法将在assertEquals中直接调用,如果返回true,则assertEquals将被调用failNotEquals
,测试结果将失败。
这是哪个版本的JUnit?我只看过delta,没看过epsilon-但这是附带问题!
从JUnit javadoc中:
delta-期望值与实际值之间的最大差额,对于这两个数字,仍然认为相等。
这可能有点过分,但是我通常使用很少的数字,例如
private static final double DELTA = 1e-15;
@Test
public void testDelta(){
assertEquals(123.456, 123.456, DELTA);
}
如果您正在使用hamcrest断言,则可以只使用equalTo()
带有两个双精度值的标准(它不使用增量)。但是,如果您想要一个增量,则可以使用closeTo()
(请参阅javadoc),例如
private static final double DELTA = 1e-15;
@Test
public void testDelta(){
assertThat(123.456, equalTo(123.456));
assertThat(123.456, closeTo(123.456, DELTA));
}
仅供参考,即将来临的JUnit 5在两次加倍调用时也将使delta成为可选项assertEquals()
。该实施(如果你有兴趣)为:
private static boolean doublesAreEqual(double value1, double value2) {
return Double.doubleToLongBits(value1) == Double.doubleToLongBits(value2);
}
事实是,由于浮点数固有的精度问题,两个double可能不完全相等。使用此增量值,您可以控制基于误差因子的相等性评估。
另外,某些浮点值可以具有可能影响结果的特殊值,例如NAN和-Infinity / + Infinity。
如果您确实打算比较两个双精度数是否相等,则最好将它们作为长整数进行比较
Assert.assertEquals(Double.doubleToLongBits(expected), Double.doubleToLongBits(result));
要么
Assert.assertEquals(0, Double.compareTo(expected, result));
可以考虑这些细微差别。
我没有深入研究有问题的Assert方法,但是我只能假定先前的方法已针对此类问题而弃用,而新方法确实将它们考虑在内。
请注意,如果您不进行数学运算,则声明确切的浮点值没有任何错误。例如:
public interface Foo {
double getDefaultValue();
}
public class FooImpl implements Foo {
public double getDefaultValue() { return Double.MIN_VALUE; }
}
在这种情况下,您要确保它确实是MIN_VALUE
,而不是零或-MIN_VALUE
或MIN_NORMAL
或其他很小的值。你可以说
double defaultValue = new FooImpl().getDefaultValue();
assertEquals(Double.MIN_VALUE, defaultValue);
但这会给您一个过时的警告。为避免这种情况,您可以致电assertEquals(Object, Object)
:
// really you just need one cast because of autoboxing, but let's be clear
assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue);
而且,如果您真的想看起来很聪明:
assertEquals(
Double.doubleToLongBits(Double.MIN_VALUE),
Double.doubleToLongBits(defaultValue)
);
或者,您可以只使用Hamcrest流利风格的断言:
// equivalent to assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue);
assertThat(defaultValue, is(Double.MIN_VALUE));
但是,如果您要检查的值确实来自数学运算,请使用epsilon。