2016-02-23 12 views
16

ich assert zwischen 2 zwei Dezimalstellen verwenden möchten, verwende ich diese:JUnit Assert mit BigDecimal

BigDecimal bd1 = new BigDecimal (1000); 
BigDecimal bd2 = new BigDecimal (1000); 
org.junit.Assert.assertSame (bd1,bd2); 

aber das JUnit-Protokoll zeigt:

expected <1000> was not: <1000> 
+0

Sie sind nicht das gleiche Objekt wie erwartet. Sie könnten prüfen, ob sie "gleich" sind. Hinweis: BigDecimal berücksichtigt "1000.0" und "1000.00" nicht als gleich, da die Anzahl der Dezimalstellen unterschiedlich ist. IMHO 'double' ist einfacher und nicht fehleranfälliger. ;) –

+0

@PeterLawrey Ich frage mich wann wird das behoben werden, kann ich wirklich nicht, wie ist das in irgendeinem Szenario nützlich. – Maroun

+0

@MarounMaroun Aus Gründen der Abwärtskompatibilität wird es nie repariert. –

Antwort

5

assertSame Tests, die die beiden Objekte die gleichen Objekte sind, dh, dass sie ==:

Asserts that two objects refer to the same object. If they are not the same, an AssertionError without a message is thrown.

In Ihrem Fall, da bd1 und bd2 beide neuen BigDecimal sind, sind die Objekte nicht gleich sind, damit die Ausnahme.

Was Sie wollen, ist assertEquals zu verwenden, das testet, ob zwei Objekte gleich sind, das heißt .equals:

Asserts that two objects are equal. If they are not, an AssertionError without a message is thrown. If expected and actual are null , they are considered equal.

BigDecimal bd1 = new BigDecimal (1000); 
BigDecimal bd2 = new BigDecimal (1000); 
org.junit.Assert.assertEquals(bd1,bd2); 
+0

Vielen Dank! Sie finden meine perfekte Lösung: D – kAnGeL

+6

das funktioniert nur für BigDecimals mit der exakt gleichen Skala –

+0

@PavloZvarych Ja, was hier der Fall ist. Es hängt davon ab, ob die Skala auch ein Parameter ist, den Sie testen möchten. – Tunaki

2

bd1 und bd2 sind zwei verschiedene Objekte und da assertSame prüft die Objektreferenz mit dem == Operator, werden Sie diese Nachricht bekommen, sehen Sie die Dokumentation:

Asserts that two objects refer to the same object. If they are not the same, an AssertionError without a message is thrown.

Sie sollten stattdessen assertEquals verwenden, es überprüft, dass die beiden Objekte gleich sind - was Sie wollen.


Beachten Sie, dass der Vergleich von zwei BigDecimal Objekte des == Operator arbeiten, solange ihre Werte zwischengespeichert werden (0 bis 10) Werte.

0

Verwenden AssertEquals statt AssertSame ... Grund, weil assertequals prüft den Wert aber assertsame Kontrollen die refrence ..

3

Verfahren assertSame Tests, die beide dasselbe Objekt sind. Sie haben jedoch zwei Objekte, die den gleichen Wert haben. Um dies zu testen, können Sie assertEquals verwenden.

Sie sollten jedoch ein unerwartetes Verhalten bei der Verwendung von assertEquals (das von der equals-Methode abhängt) unter BigDecimal s beachten. Zum Beispiel new BigDecimal("100").divide(new BigDecimal("10.0")).equals(new BigDecimal("10")) wertet false aus, weil equals auch im Maßstab der BigDecimal Instanzen aussieht.

In vielen Fällen ist es besser, BigDecimal s unter Verwendung des compareTo Methode zum Vergleich:

assertTrue(bd1.compareTo(bd2) == 0); 
13

assertSame prüft, ob beide Objekte dieselbe Instanz sind. assertEquals überprüft, ob die Zahlen in Wert und Maßstab gleich sind, d.h. 1000 ist nicht gleich 1000,00. Wenn Sie nur den numerischen Wert vergleichen möchten, sollten Sie compareTo() Methode von BigDecimal verwenden.

Zum Beispiel:

BigDecimal bd1 = new BigDecimal (1000.00); 
BigDecimal bd2 = new BigDecimal (1000); 
org.junit.Assert.assertTrue(bd1.compareTo(bd2) == 0); 
+1

'comparesEqualTo()' ist dies vorzuziehen, da 'assertThat (x.compareTo (y), is (y)' in '' '' '' erwartet ergibt: is <0> aber: war <1> '.' AssertThat (x, comparesEqualTo (y) 'gibt' Erwartet: ein Wert gleich <27700> aber: <6700.000> war weniger als <27700> ' – slim

+0

@slim Ja, die Antwort mit Hamcrest gibt eine aussagekräftigere Fehlermeldung.Meine Antwort auf der anderen Seite ist nicht von Hamcrest abhängig und erklärt die Logik, warum die akzeptierte Antwort fehlschlagen kann – Endery

5

BigDecimal mit compareTo() Werken Vergleicht man (wie in: den Maßstab ignorieren und die tatsächliche Zahl vergleichen), aber wenn Unit-Tests ist es nützlich zu wissen, was die tatsächliche Zahl ist, speziell wenn der Test Scheitern.

Eine Option, die ich in diesem Fall nicht verwendet habe, ist stripTrailingZeros() auf beide BigDecimal:

assertEquals(new BigDecimal("150").stripTrailingZeros(), 
        otherBigDecimal.stripTrailingZeros()); 

diese Funktion Was ist Nullen nicht entfernt, ohne die Zahl zu ändern, so wird "150" in "1.5E+2" umgewandelt: auf diese Weise ist es doesn t egal, ob Sie 150, 150.00 oder ein anderes Formular in otherBigDecimal haben, weil sie normalisiert in die gleiche Form erhalten.

Der einzige Unterschied ist ein null in otherBigDecimal würde eine NullPointerException anstelle einer Assertion Fehler geben.

22

Die official junit solution zu behaupten, dass zwei BigDecimal matematisch gleich sind, ist Hamcrest zu verwenden.

Mit java-hamcrest 2.0.0.0 können wir diese Syntax verwenden:

// import static org.hamcrest.MatcherAssert.assertThat; 
    // import org.hamcrest.Matchers; 

    BigDecimal a = new BigDecimal("100") 
    BigDecimal b = new BigDecimal("100.00") 
    assertThat(a, Matchers.comparesEqualTo(b)); 

Hamcrest 1.3 Quick Reference

+1

Dies gibt auch eine sinnvolle Fehlermeldung im Vergleich zu akzeptiert und am höchsten gewählten Antwort: "java.lang.AssertionError: Erwartet: ein Wert gleich <0.22> aber: <0.222> war größer als <0.22>" – Zotov