Warum ist assertEquals (double, double) in JUnit veraltet?

72

Ich habe mich gefragt warum assertEquals(double, double) veraltet ist.

ich benutzte import static org.junit.Assert.assertEquals; habe JUnit 4.11 und verwendet.

Unten ist mein Code:

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() gibt einen doppelten Wert zurück.

Was könnte falsch sein?

jsh6303
quelle
6
Wenn Sie einfach das Javadoc lesen, wird Ihnen gesagt, was Sie stattdessen verwenden sollen.
Andreas
Versuchen Sie es wieAssert.assertEquals(2.49, 2.49, 0.1);
Arjun Kalidas
Wenn ich JUnit wäre, würde ich den Test doublezur Darstellung von Geldbeträgen anstelle einer Bibliotheksklasse eines Drittanbieters oder einer benutzerdefinierten Klasse speziell für Geld nicht bestehen.
Alonso del Arte

Antworten:

94

Es ist wegen der Präzisionsprobleme des Doppelten veraltet.

Wenn Sie bemerken, gibt es eine andere Methode assertEquals(double expected, double actual, double delta), die einen deltaPräzisionsverlust ermöglicht .

JavaDoc :

Behauptet, dass zwei Doppel innerhalb eines positiven Deltas liegen. Ist dies nicht der Fall, wird ein AssertionError ausgelöst. Wenn der erwartete Wert unendlich ist, wird der Delta-Wert ignoriert. NaNs werden als gleich angesehen: assertEquals(Double.NaN, Double.NaN, *)Durchgänge

...

Delta - das maximale Delta zwischen erwartet und tatsächlich, für das beide Zahlen immer noch als gleich angesehen werden.

Codebender
quelle
1
@JiajuShen, es hängt von Ihren Berechnungen ab ... Sagen wir, wenn Sie dies tun 5.1 + 0.1, würden Sie erwarten, 5.2aber die Ausgabe wäre 5.1999.... So kann das Delta sein 0.0001... oder noch weniger ...
Codebender
1
Schauen Sie sich dieses Beispiel aus dem JUnit-Quellcode oder dieses Beispiel an
Eric
20

Die Leute erklären, geben aber keine Proben ... Also hier ist, was für mich funktioniert hat:

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

Das 0am Ende;

Victor Augusto
quelle
13
Die Verwendung von 0.0 als Delta entspricht der Verwendung der veralteten Methode. Das Delta soll widerspiegeln, wie nahe die Zahlen sein können und dennoch als gleich angesehen werden. Verwenden Sie Werte wie 0,1 oder 0,01 oder 0,001 usw., je nachdem, wie viel Fehler die Anwendung tolerieren kann.
Downeyt
2
Dies ist ein schlechter Rat. Durch die 0 vollständige Verwendung wird der Zweck der Verwendung der nicht veralteten Methode zunichte gemacht. Es ist genau das gleiche wie bei Verwendung der veralteten Variante. Dies ist umso gefährlicher, als Sie keine Warnung mehr erhalten. Erkennen Sie den Grund, warum es veraltet war, und verwenden Sie ein kleines Delta wie 0.00001.
Zabuzard
18

assertEquals(double, double) wird nicht mehr empfohlen, da die beiden Doppelwerte möglicherweise gleich sind. Wenn es sich jedoch um berechnete Werte handelt, kann der Prozessor sie zu geringfügig unterschiedlichen Werten machen.

Wenn Sie dies versuchen, wird es fehlschlagen : assertEquals(.1 + .7, .8). Dies wurde mit einem Intel® Prozessor getestet .

Wenn Sie die veraltete Methode aufrufen, wird der Aufruf ausgelöst fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers");.

Eric
quelle
1

Alte Frage, aber das wurde noch nicht gesagt und könnte jemandem helfen.

Mit können com.google.common.math.DoubleMath.fuzzyEquals(double a, double b, double tolerance)Sie festlegen, wie nahe die beiden Doppelbilder beieinander liegen sollen.

Ich fand es sehr praktisch für Unit-Tests, bei denen ich Testergebniswerte nicht mit vielen Dezimalstellen fest codieren möchte.

steven35
quelle