我想在两个小数之间使用assert,我使用以下代码:
BigDecimal bd1 = new BigDecimal (1000);
BigDecimal bd2 = new BigDecimal (1000);
org.junit.Assert.assertSame (bd1,bd2);
但是JUnit日志显示:
expected <1000> was not: <1000>
我想在两个小数之间使用assert,我使用以下代码:
BigDecimal bd1 = new BigDecimal (1000);
BigDecimal bd2 = new BigDecimal (1000);
org.junit.Assert.assertSame (bd1,bd2);
但是JUnit日志显示:
expected <1000> was not: <1000>
官方JUnit解决方案用于断言两个BigDecimal数值是否相等是使用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));
java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
- StewartassertSame
检查两个对象是否为同一实例。 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);
comparesEqualTo()
比这更好,因为在失败时,assertThat(x.compareTo(y), is(y))
会返回类似于Expected: is <0> but: was <1>
的信息。而assertThat(x, comparesEqualTo(y))
则会返回Expected: a value equal to <27700> but: <6700.000> was less than <27700>
。 - slim这个问题的答案已经给出。但有些回答回答了另一个问题,即“如何比较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()
进行比较是可行的(它忽略了小数位并比较实际数字),但在单元测试中,了解实际数字是非常有用的,特别是当测试失败时。
我在这种情况下使用的一个选项是对两个 BigDecimal
都使用 stripTrailingZeros()
:
assertEquals(new BigDecimal("150").stripTrailingZeros(),
otherBigDecimal.stripTrailingZeros());
这个函数的作用是去掉数字中的零,但不改变数字本身,因此"150"
被转换为"1.5E+2"
。这样做的好处是无论你在otherBigDecimal
中有150
、150.00
或其他形式,它们都会被规范化为相同的形式。otherBigDecimal
中出现null
将导致一个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
实例的标度。compareTo
方法来比较BigDecimal
。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
,它检查两个对象是否相等 - 这正是你想要的。
==
运算符比较两个BigDecimal
对象只有在它们的值被缓存(0到10)时才会起作用。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());
在比较之前,这将把结果缩小到最低可能的范围。
1000.0
和1000.00
相等,因为小数位数不同。在我看来,double
更简单,而且错误更少。;) - Peter Lawrey