我正在回答有关 JUnit 5 的更新。无论版本如何,assertEquals(Double expected, Double actual) 都会被路由到 assertEquals(Object expected, Object actual),因为正如其他人已经解释的那样,Double 是一个隐式扩展 Object 的原始包装器。
但是 JUnit 4 上下文中的 assertEquals(double expected, double actual)(使用两个原语而不是两个原语包装器)调用了一个已弃用的过程。我不知道它是否已经在 JUnit 3 中被弃用。但猜猜看:它在 JUnit 5 中没有被弃用。
像double 这样的浮点类型本质上是不精确的。假设expected = 0.3。 actual 是如何计算的?如果是3.0 / 10,结果可能是准确的。但如果是臭名昭著的0.1 + 0.2,它会偏离 0.00000000000000004(如果减去 0.3,它会变成 5.551115123125783 × 10-17)。
一般来说,浮点乘除比浮点加减可靠。
以下示例来自具有 org.junit.jupiter.api.Assertions.* 静态导入的测试类。
@Test
void testDeltaExample() {
double expected = 0.3;
double actual = 0.1 + 0.2;
assertEquals(expected, actual);
}
结果:
org.opentest4j.AssertionFailedError: 预期: 但是是:
在
org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55) 在
org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
在
org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:70)
在
org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:65)
在 org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:868)
...
您是否关心它是否会像这样减少一点点?如果你不这样做,那么你会想要一个像 0.0000000000000001 这样的增量。
如果您愿意,您仍然可以使用 JUnit 5 中的“老式”JUnit(但除了迁移现有测试套件或看到它可以完成之外,您不应该出于任何原因想要这样做)。
@Test
void testDeltaExample() {
double expected = 0.3;
double actual = 0.1 + 0.2;
org.junit.Assert.assertEquals(expected, actual);
}
(您的 IDE 应该在右大括号之前的行中显示删除线)。即使expected 和actual 具有完全相同的位模式(在本例中不会),此测试也会失败。
java.lang.AssertionError: 使用 assertEquals(expected, actual, delta)
比较浮点数
org.junit.Assert.fail(Assert.java:88) 在
org.junit.Assert.assertEquals(Assert.java:667) 在
org.junit.Assert.assertEquals(Assert.java:656)
...
许多非常聪明的 Java 程序员学习了 SQL 连接等复杂的东西,根本不关心浮点数,所以他们只使用 0.0 的 delta。
因此,JUnit 开发人员似乎认为教育人们了解浮点的弱点不是他们的工作。所以org.junit.jupiter.api.Assertions.assertEquals(double expected, double actual) 在技术上是新的,并没有被弃用。
绝对清楚,浮点与增量的比较在 JUnit 5 中仍然可用。从 Scala 的角度来看,您可以将其视为 assertEquals(expected: Double, actual: Double, delta: Double = 0.0)。