JUnit 断言 BigDecimal

JUnit Assert with BigDecimal

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

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

但 JUnit 日志显示:

expected <1000> was not: <1000>

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

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

您应该改用 assertEquals,它会检查两个对象是否相等 - 这正是您想要的。


请注意,使用 == 运算符比较两个 BigDecimal 对象将起作用,只要它们的值被缓存(从 0 到 10)值。

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

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

在你的例子中,由于 bd1bd2 都是新的 BigDecimal,对象不一样,因此是例外。

你想要的是使用 assertEquals,测试两个对象是否相等,即 .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);

使用 AssertEquals 而不是 AssertSame...原因是因为 assertequals 检查值但 assertsame 检查引用..

方法assertSame测试两者是同一个对象。但是,您有两个具有相同值的对象。要对此进行测试,您可以使用 assertEquals.

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

在许多情况下,最好使用 compareTo 方法比较 BigDecimal

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

assertSame检查两个对象是否是同一个实例。 assertEquals检查数字的值和比例是否相等,即 1000 不等于 1000.00。如果只想比较数值,则应使用 BigDecimal.

中的 compareTo() 方法

例如:

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

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

我在这种情况下使用的选项是 stripTrailingZeros() BigDecimal:

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

这个函数所做的是在不改变数字的情况下删除零,所以 "150" 被转换为 "1.5E+2":这样,如果你有 150150.00otherBigDecimal 中的其他形式,因为它们 标准化 为相同的形式。

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

断言两个 BigDecimal 在数学上相等的 official junit solution 是使用 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 Quick Reference

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

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

你不能像在 :

中那样使用 toString()
assertEquals("0.02", taxes.toString());

其中税收是 BigDecimal。

问题的答案已经给出。但是有些答案回答了另一个问题,即'how to compare 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);