我想在 2 两位小数之间使用断言,我用这个:
BigDecimal bd1 = new BigDecimal (1000);
BigDecimal bd2 = new BigDecimal (1000);
org.junit.Assert.assertSame (bd1,bd2);
但 JUnit 日志显示:
expected <1000> was not: <1000>
断言两个 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));
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);
问题的答案已经给出了。但有些答案回答了另一个问题,即“如何比较 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);
将
BigDecimal
与 compareTo()
进行比较是可行的(例如:它忽略比例并比较实际数字),但是在单元测试时,了解实际数字是有用的,特别是当测试失败时。
我在这种情况下使用的一个选项是
stripTrailingZeros()
和 BigDecimal
:
assertEquals(new BigDecimal("150").stripTrailingZeros(),
otherBigDecimal.stripTrailingZeros());
此函数的作用是在不更改数字的情况下删除零,因此
"150"
会转换为 "1.5E+2"
:这样,无论 150
、150.00
或其他形式的 otherBigDecimal
都没有关系,因为它们将归一化变成相同的形式。
唯一的区别是
null
中的 otherBigDecimal
会给出 NullPointerException
而不是断言错误。
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);
方法
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);
特定比例和四舍五入的其他替代方案:
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);
assertThat(BigDecimal.valueOf(10.00)).isEqualByComparingTo(BigDecimal.valueOf(10));
bd1
和bd2
是两个不同对象,并且由于assertSame
使用==
运算符检查对象引用,您会收到该消息,请参阅文档:
断言两个对象引用同一个对象。如果它们不相同,则会抛出不带消息的
。AssertionError
您应该使用
assertEquals
来代替,它检查两个对象是否相等 - 这就是您想要的。
请注意,只要缓存了(0 到 10)值,使用
BigDecimal
运算符比较两个 ==
对象就可以工作。
如果您喜欢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());
这将在比较之前将结果降低到尽可能低的比例。
我正在使用 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);
使用
AssertEquals
而不是 AssertSame
...原因是因为 assertequals
检查值,但 assertsame
检查参考..