JUnit Assert avec BigDecimal

Je veux utiliser assert entre 2 deux décimales, j'utilise ceci:

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

Mais le journal JUnit montre:

expected <1000> was not: <1000>
25
demandé sur Tunaki 2016-02-23 12:08:47

8 réponses

assertSame les tests que les deux objets sont les mêmes objets, c'est à dire qu'ils sont ==:

Affirme que deux objets se réfèrent au même objet. Si elles ne sont pas identiques, un AssertionError sans message est lancé.

Dans votre cas, puisque bd1 et bd2 sont tous deux nouveaux BigDecimal, les objets ne sont pas les mêmes, d'où l'exception.

Ce que vous voulez est d'utiliser assertEquals, qui teste si deux objets sont égaux, c'est à dire .equals:

Affirme que deux objets sont égaux. Si ce n'est pas le cas, un AssertionError sans message est lancé. Si attendu et réel sont null, ils sont considérés comme égaux.

BigDecimal bd1 = new BigDecimal (1000);
BigDecimal bd2 = new BigDecimal (1000);
org.junit.Assert.assertEquals(bd1,bd2);
6
répondu Tunaki 2016-02-23 09:12:07

La solution junit officielle pour affirmer que deux BigDecimal sont matématiquement égaux consiste à utiliser hamcrest.

Avec java-hamcrest 2.0.0.0, nous pouvons utiliser cette syntaxe:

    // 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 Référence Rapide

32
répondu frhack 2017-11-21 16:27:17

assertSamevérifie si les deux objets sont la même instance. assertEquals vérifie si les nombres sont égaux en valeur et en échelle, cela signifie que c'est-à-dire 1000 n'est pas égal à 1000.00. Si vous voulez comparer seule la valeur numérique, vous devez utiliser compareTo() méthode de BigDecimal.

Par exemple:

BigDecimal bd1 = new BigDecimal (1000.00);
BigDecimal bd2 = new BigDecimal (1000);
org.junit.Assert.assertTrue(bd1.compareTo(bd2) == 0); 
18
répondu Endery 2016-02-23 09:35:38

Comparer BigDecimal avec compareTo() fonctionne (comme dans: il ignore l'échelle et compare le nombre réel) mais lors des tests unitaires, il est utile de savoir quel est le nombre réel, spécialement lorsque le test échoue.

Une option que j'ai utilisée dans ce cas est {[3] } sur les deux BigDecimal:

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

Ce que cette fonction fait est de supprimer des zéros sans changer le nombre, donc "150" est converti en "1.5E+2": de cette façon, peu importe si vous avez 150, 150.00 ou autre forme dans otherBigDecimal parce qu'ils obtiennent normalisé dans la même forme.

La seule différence est un null dans otherBigDecimal donnerait un NullPointerException au lieu d'une erreur d'assertion.

6
répondu Daniele Segato 2017-01-31 08:17:34

La méthode assertSame teste que les deux sont le même objet. Cependant, vous avez deux objets qui ont la même valeur. Pour tester cela, vous pouvez utiliser assertEquals.

Cependant, vous devez être conscient de certains comportement inattendu lors de l'utilisation de assertEquals (qui dépend de la equals méthode) sur BigDecimals. Par exemple, new BigDecimal("100").divide(new BigDecimal("10.0")).equals(new BigDecimal("10")) donne false, car equals intéresse également à l'échelle de la BigDecimal instances.

Dans de nombreuses circonstances, il est préférable de comparer BigDecimal s en utilisant la méthode compareTo:

assertTrue(bd1.compareTo(bd2) == 0);
4
répondu Hoopje 2016-12-05 07:36:33

bd1 et bd2 deux différente objets, et depuis assertSame vérifie la référence d'objet à l'aide de la == opérateur, vous obtenez ce message, consultez la documentation:

Affirme que deux objets se réfèrent au même objet . Si elles ne sont pas identiques, un AssertionError sans message est lancé.

Vous devriez utiliser assertEquals à la place, il vérifie que les deux objets sont égaux-ce qui est ce que vous voulez.


Notez que la comparaison de deux objets BigDecimal à l'aide de l'opérateur == fonctionnera tant que leurs valeurs sont mises en cache (pour les valeurs 0 à 10).

2
répondu Maroun 2016-02-23 09:23:39

Utiliser AssertEquals au lieu de AssertSame... la raison assertequals vérifie la valeur, mais assertsame vérifie la refrence..

0
répondu Vikrant Kashyap 2016-02-23 09:13:14

Autre variante pour une échelle spécifique et arrondie:

import static org.assertj.core.api.Assertions.assertThat;

...

BigDecimal a = new BigDecimal(100.05);
BigDecimal b = new BigDecimal(100.048);

a = a.setScale(2, BigDecimal.ROUND_HALF_EVEN);
b = b.setScale(2, BigDecimal.ROUND_HALF_EVEN);

assertThat(a).isEqualTo(b);
0
répondu alditis 2018-03-14 20:40:37