2016-02-23 24 views
16

voglio usare assert tra 2 due decimali, io uso questo:JUnit Assert con BigDecimal

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

ma il registro JUnit mostra:

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

Non sono lo stesso oggetto come previsto. Si potrebbe cercare di verificare se sono 'uguali' Nota: BigDecimal non considera' 1000.0' e '1000.00' come il numero di cifre decimali sono diversi. IMHO 'double' è più semplice e non più soggetto a errori. ;) –

+0

@PeterLawrey Mi chiedo quando sarà corretto, non posso davvero come è utile in qualsiasi scenario. – Maroun

+0

@ MarounMaroun Per compatibilità con le versioni precedenti, non verrà mai riparato. –

risposta

5

assertSame prove che i due oggetti sono gli stessi oggetti, vale a dire che sono ==:

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

Nel suo caso, poiché bd1 e bd2 sono entrambi nuovo BigDecimal, gli oggetti non sono uguali, quindi l'eccezione.

Che cosa si vuole è quello di utilizzare assertEquals, che i test se due oggetti sono uguali, cioè .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

Grazie mille! Trovi la mia soluzione perfetta: D – kAnGeL

+6

che funzionerà solo per BigDecimals con la stessa identica scala –

+0

@PavloZvarych Sì, come nel caso qui. Dipende se la scala è un parametro che vuoi testare. – Tunaki

2

bd1 e bd2 sono due differenti oggetti e dal momento che assertSame controlla il riferimento dell'oggetto utilizzando l'operatore ==, viene visualizzato il messaggio, consultare la documentazione:

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

È necessario utilizzare assertEquals, invece, controlla che i due oggetti siano uguali - che è ciò che si desidera.


noti che confrontare due BigDecimal oggetti utilizzando l'operatore == funzioneranno finché i loro valori vengono memorizzati nella cache (per 0 a 10) valori.

0

Uso AssertEquals invece di AssertSame ... Motivo perchè assertequals controlla il valore, ma assertsame controlli il refrence ..

3

Il metodo assertSame verifica che entrambi siano lo stesso oggetto. Tuttavia, hai due oggetti che hanno lo stesso valore. Per verificare ciò, è possibile utilizzare assertEquals.

Tuttavia, è necessario conoscere alcuni comportamenti imprevisti quando si utilizza assertEquals (che dipende dal metodo equals) su BigDecimal s. Ad esempio, new BigDecimal("100").divide(new BigDecimal("10.0")).equals(new BigDecimal("10"))10 viene valutato su false perché equals analizza anche la scala delle istanze BigDecimal.

In molte circostanze è meglio confrontare BigDecimal s utilizzando il metodo compareTo:

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

assertSame controlla se entrambi gli oggetti sono la stessa istanza. assertEquals controlla se i numeri sono uguali in valore e scala, ciò significa che 1000 non è uguale a 1000,00. Se si desidera confrontare solo il valore numerico, è necessario utilizzare il metodo compareTo() da BigDecimal.

Ad esempio:

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

'comparesEqualTo()' è preferibile a questo, in caso di errori, 'assertThat (x.compareTo (y), is (y)' fornisce qualcosa come Expected: è <0> ma: era <1> '. AssertThat (x, compareEqualTo (Previsto: un valore pari a <27700> ma: <6700.000> era inferiore a <27700> ' – slim

+0

@slim Sì, la risposta con Hamcrest fornisce un messaggio di errore più significativo.La mia risposta, d'altra parte, non dipende da Hamcrest e spiega la logica del perché la risposta accettata può fallire – Endery

5

Confrontando BigDecimal con compareTo() opere (come in: esso ignorare la scala e confronta il numero reale), ma quando unit test è utile sapere qual è il numero effettivo, specialmente quando il test fallire.

Un'opzione che ho usato in questo caso è stripTrailingZeros() su entrambi BigDecimal:

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

Cosa questa funzione non fa altro che togliere gli zeri senza modificare il numero, quindi "150" viene convertito in "1.5E+2": in questo modo esso doesn' t importa se hai 150, 150.00 o altro modulo in otherBigDecimal perché ottengono normalizzato nello stesso modulo.

L'unica differenza è un in otherBigDecimal darebbe un NullPointerException invece di un errore di asserzione.

22

Il official junit solution per affermare che due BigDecimal sono matematicamente uguali significa utilizzare hamcrest.

Con java-hamcrest 2.0.0.0 possiamo usare questa sintassi:

// 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

Questo dà anche un messaggio di errore significativo rispetto alla risposta accettata e più votata: "java.lang.AssertionError: Previsto: un valore uguale a <0.22> ma: <0.222> era maggiore di <0.22>" – Zotov