为什么在JUnit中不推荐使用assertEquals(double,double)?


72

我想知道为什么assertEquals(double, double)不推荐使用。

我曾经import static org.junit.Assert.assertEquals;使用过JUnit 4.11。

下面是我的代码:

import org.junit.Test;
import static org.junit.Assert.assertEquals;


public class AccountTest {

@Test
public void test() {
    Account checking = new Account(Account.CHECKING);
    checking.deposit(1000.0);
    checking.withdraw(100.0);
    assertEquals(900.0, checking.getBalance());
   }
}

checking.getBalance() 返回一个双精度值。

有什么事吗


6
如果您只是阅读Javadoc,则会被告知要使用什么。
安德里亚斯

尝试像使用它Assert.assertEquals(2.49, 2.49, 0.1);
Arjun Kalidas

如果我是JUnit,则我将无法通过double用来表示金额而不是某些第三方库类或专门用于货币的自定义类的测试而失败。
阿隆索阿尔特

Answers:


94

由于double的精度问题而已弃用。

如果您注意到,还有另一种assertEquals(double expected, double actual, double delta)允许delta精度损失的方法。

JavaDoc

断言两个双打等于正增量内。如果不是,则会引发AssertionError。如果期望值是无穷大,则将忽略增量值.NaN被视为相等:assertEquals(Double.NaN, Double.NaN, *)通过

...

delta-期望值与实际值之间的最大差额,对于这两个数字,仍然认为相等。


1
@JiajuShen,这取决于您的计算...假设您这样做5.1 + 0.1,则可以预期,5.2但输出将是5.1999...。因此,增量可以是0.0001……甚至更低……
Codebender 2015年

1
检查出这个例子从JUnit的源代码或本示例
埃里克

20

人们会解释但不提供示例...因此,对我有用的是:

@Test
public void WhenMakingDepositAccountBalanceIncreases() {
    Account account = new Account();
    account.makeDeposit(10.0);
    assertEquals("Account balance was not correct.", 10.0, account.getBalance(), 0);
}

0到底;


13
使用0.0作为增量与使用不赞成使用的方法相同。增量旨在反映数字可以接近并且仍然被认为相等的程度。根据应用程序可以容忍的错误程度,使用0.1或0.01或0.001等值。
downeyt

2
这是一个不好的建议。使用0 完全会破坏使用未弃用方法的目的。与使用不推荐使用的变体完全相同。由于您不再收到警告,因此更加危险。确认不推荐使用它的原因,并使用一个小的delta 0.00001
Zabuzard

18

assertEquals(double, double) 不建议使用此参数,因为两个double可能相同,但是如果它们是计算得出的值,则处理器可能会将它们设为稍有不同的值。

如果尝试这样做,它将失败:assertEquals(.1 + .7, .8)使用英特尔®处理器对此进行了测试

调用不推荐使用的方法将触发fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers");被调用。


1

旧问题,但这尚未被提及,可能会帮助某人。

您可以使用 com.google.common.math.DoubleMath.fuzzyEquals(double a, double b, double tolerance)来指定两个双打之间的距离。

我发现它对于单元测试非常方便,因为我不想用很多小数位来硬编码测试结果值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.