JUnit 使用 BigDecimal 断言

问题描述 投票:0回答:12

我想在 2 两位小数之间使用断言,我用这个:

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

但 JUnit 日志显示:

expected <1000> was not: <1000>
java junit assert bigdecimal
12个回答
139
投票

断言两个 BigDecimal 在数学上相等的官方 junit 解决方案是使用 hamcrest。

使用 java-hamcrest 2.0.0.0 我们可以使用以下语法:

    // 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 快速参考


48
投票

assertSame
检查两个对象是否是同一实例。
assertEquals
检查数字的值和比例是否相等,即 1000 不等于 1000.00。如果您只想比较数值,您应该使用
compareTo()
中的
BigDecimal
方法。

例如:

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

18
投票

问题的答案已经给出了。但有些答案回答了另一个问题,即“如何比较 2 个 BigDecimals?”。到目前为止给出的解决方案要么是错误的,要么是过时的。我想建议尝试一下:

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

BigDecimal a = new BigDecimal("100")
BigDecimal b = new BigDecimal("100.00")
assertThat(a).isEqualByComparingTo(b);

16
投票

BigDecimal
compareTo()
进行比较是可行的(例如:它忽略比例并比较实际数字),但是在单元测试时,了解实际数字是有用的,特别是当测试失败时。

我在这种情况下使用的一个选项是

stripTrailingZeros()
BigDecimal
:

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

此函数的作用是在不更改数字的情况下删除零,因此

"150"
会转换为
"1.5E+2"
:这样,无论
150
150.00
或其他形式的
otherBigDecimal
都没有关系,因为它们将归一化变成相同的形式。

唯一的区别是

null
中的
otherBigDecimal
会给出
NullPointerException
而不是断言错误。


9
投票

assertSame
测试这两个对象是相同的对象,即它们是
==
:

断言两个对象引用同一个对象。如果它们不相同,则会抛出一个不带消息的

AssertionError

在您的情况下,由于

bd1
bd2
都是新的
BigDecimal
,因此对象不相同,因此例外。

你想要的是使用

assertEquals
,测试两个对象是否相等,即
.equals
:

断言两个对象相等。如果不是,则会抛出一个不带消息的

AssertionError
。如果预期值和实际值是
null
,则它们被认为是相等的。

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

8
投票

方法

assertSame
测试两者是否是同一个对象。但是,您有两个具有相同值的对象。要测试这一点,您可以使用
assertEquals

但是,在

assertEquals
上使用
equals
(取决于
BigDecimal
方法)时,您应该注意一些意外行为。例如,
new BigDecimal("100").divide(new BigDecimal("10.0")).equals(new BigDecimal("10"))
的计算结果为
false
,因为
equals
还会查看
BigDecimal
实例的规模。

在许多情况下,最好使用

BigDecimal
方法来比较
compareTo

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

3
投票

特定比例和四舍五入的其他替代方案:

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);

2
投票
assertThat(BigDecimal.valueOf(10.00)).isEqualByComparingTo(BigDecimal.valueOf(10));

1
投票

bd1
bd2
是两个不同对象,并且由于
assertSame
使用==运算符检查
对象引用
,您会收到该消息,请参阅文档:

断言两个对象引用同一个对象。如果它们不相同,则会抛出不带消息的

AssertionError

您应该使用

assertEquals
来代替,它检查两个对象是否相等 - 这就是您想要的。


请注意,只要缓存了(0 到 10)值,使用

BigDecimal
运算符比较两个
==
对象就可以工作。


0
投票

如果您喜欢assertEquals,因为它显示失败消息中的值,并且您想忽略无关的尾随十进制零,则可以使用以下内容:

BigDecimal bdGood = BigDecimal.valueOf(2.5).setScale(3);
BigDecimal bdBad = BigDecimal.valueOf(2.504);
assertEquals("Passes", BigDecimal.valueOf(2.5), bdGood.stripTrailingZeros());
assertEquals("Fails", BigDecimal.valueOf(2.5), bdBad.stripTrailingZeros());

这将在比较之前将结果降低到尽可能低的比例。


0
投票

我正在使用 assertEquals 和 assertTrue 从 Map 和断言中检索 Bigdecimal。小数值是使用 setScale() 方法完成的。

   Map<String, BigDecimal> amtAdjustedMap = new HashMap<>();

    Assertions.assertEquals(amtAdjustedMap.get("amtAdjustedLcy"),new BigDecimal(100000));
    Assertions.assertEquals(amtAdjustedMap.get("amtAdjustedFxRate"),new BigDecimal(7.81676).setScale(5, RoundingMode.HALF_UP));
    Assertions.assertEquals(amtAdjustedMap.get("fxRateAdjustment"),BigDecimal.ONE);

    Assertions.assertTrue(amtAdjustedMap.get("amtAdjustedLcy").compareTo(new BigDecimal(100000))==0);
    Assertions.assertTrue(amtAdjustedMap.get("amtAdjustedFxRate").compareTo(new BigDecimal(7.81676).setScale(5, RoundingMode.HALF_UP))==0);
    Assertions.assertTrue(amtAdjustedMap.get("fxRateAdjustment").compareTo(BigDecimal.ONE)==0);

-1
投票

使用

AssertEquals
而不是
AssertSame
...原因是因为
assertequals
检查值,但
assertsame
检查参考..

© www.soinside.com 2019 - 2024. All rights reserved.