AssertJ在不考虑小数位的情况下无法断言BigDecimal的相等性。

huangapple go评论90阅读模式
英文:

AssertJ fails to assert BigDecimal equality without scale

问题

我正在进行如下的断言测试:

assertThat(obj.getTotal()).isEqualTo(BigDecimal.valueOf(4))

我得到的结果是:

> 期望值:
<4.00>
等于:
<4>

然后我尝试了这个:

assertThat(obj.getTotal()).isEqualTo(BigDecimal.valueOf(4.00))

> 期望值:
<4.00>
等于:
<4.0>

我找到了一个解决方法,即将期望值 4 的小数位设置为 4.00,但是我觉得对于我测试中的所有 BigDecimal 变量都这样做有些烦人。我是否还不知道 AssertJ 中的更好方法呢?

英文:

I am running assertions like so:

assertThat(obj.getTotal()).isEqualTo(BigDecimal.valueOf(4))

I am getting

> Expecting:
<4.00>
to be equal to:
<4>

so then I tried

assertThat(obj.getTotal()).isEqualTo(BigDecimal.valueOf(4.00))

> Expecting:
<4.00>
to be equal to:
<4.0>

I found a workaround in which I would set the scale of expected value 4 to 4.00, but it seems quite irritating that I have to do so for all BigDecimal variables in my tests. Is there a better way from AssertJ that I am unaware of?

答案1

得分: 30

你可以使用 isEqualByComparingTo 或者 usingComparator,它们使用 BigDecimal.compareTo 来比较实际的数值。根据 JavaDoc 中的描述,equals 方法(默认的 assertj 使用的方法)执行以下操作:

> 与 compareTo 不同,该方法仅在两个 BigDecimal 对象在值和标度上相等时才将它们视为相等(因此通过此方法比较时,2.0 与 2.00 不相等)。

因此你可以这样写:

assertThat(obj.getTotal())
    .usingComparator(BigDecimal::compareTo)
    .isEqualTo(BigDecimal.valueOf(4.00));

或者简单地:

assertThat(obj.getTotal())
    .isEqualByComparingTo(BigDecimal.valueOf(4.00));

在与 Iterableextracting 断言一起使用时:

assertThat(asList(new Trade("1", new BigDecimal("5.200")), new Trade("2", new BigDecimal("4.00"))))
    .extracting(Trade::getId, Trade::getAmount)
    .usingComparatorForType(BigDecimal::compareTo, BigDecimal.class)
    .usingRecursiveFieldByFieldElementComparator()
    .containsExactlyInAnyOrder(tuple("1", new BigDecimal("5.2")), tuple("2", new BigDecimal("4")));
英文:

You can use isEqualByComparingTo or usingComparator that use BigDecimal.compareTo which compares the actual numeric value. The equals method which is the default assertj uses does the following according to JavaDoc:

> Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method).

So you can do:

    assertThat(obj.getTotal())
        .usingComparator(BigDecimal::compareTo)
        .isEqualTo(BigDecimal.valueOf(4.00));

or simply:

assertThat(obj.getTotal())
    .isEqualByComparingTo(BigDecimal.valueOf(4.00));

To use with Iterable and extracting assertions:

    assertThat(asList(new Trade(&quot;1&quot;, new BigDecimal(&quot;5.200&quot;)), new Trade(&quot;2&quot;, new BigDecimal(&quot;4.00&quot;))))
        .extracting(Trade::getId, Trade::getAmount)
        .usingComparatorForType(BigDecimal::compareTo, BigDecimal.class)
        .usingRecursiveFieldByFieldElementComparator()
        .containsExactlyInAnyOrder(tuple(&quot;1&quot;, new BigDecimal(&quot;5.2&quot;)), tuple(&quot;2&quot;, new BigDecimal(&quot;4&quot;)));

答案2

得分: -3

尝试使用 java.math.BigDecimal.stripTrailingZeros() 方法,就像这样:

// AssertJ
assertThat(obj.getTotal().stripTrailingZeros()).isEqualTo(BigDecimal.valueOf(4));

// Junit
assertEquals(BigDecimal.valueOf(4), obj.getTotal().stripTrailingZeros());
英文:

Try java.math.BigDecimal.stripTrailingZeros() method, like this:

// AssertJ
assertThat(obj.getTotal().stripTrailingZeros()).isEqualTo(BigDecimal.valueOf(4));

// Junit
assertEquals(BigDecimal.valueOf(4), obj.getTotal().stripTrailingZeros());

huangapple
  • 本文由 发表于 2020年9月3日 07:09:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63714635.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定