Smajl
Smajl

Reputation: 7995

How to test BigDecimal values

I am trying to unit test some methods producing BigDecimal outputs but I am quite confused with the varying precissio:

assertEquals(BigDecimal.valueOf(20), result);

I recently switched from crating BigDecimal values using constructor (new BigDecimal(value) to using valueOf(value)) and my tests are complaining:

Expected :20
Actual   :20.00

Setting BigDecimal.valueOf(20.00) is not helping so my question is, what is the correct way to test these floating point BigDecimal instances? Most of my test cases will have zeros after the floating point.

Upvotes: 4

Views: 8697

Answers (2)

Mark Rotteveel
Mark Rotteveel

Reputation: 109079

The problem is that BigDecimal.equals follows this rule:

Compares this BigDecimal with the specified Object for equality. 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).

And 20 and 20.00 don't have the same scale.

You need to use either

new BigDecimal("20.00")

or

BigDecimal.valueOf(20).setScale(2)

or, if you like more esoteric options

BigDecimal.valueof(2000, 2)

The problem with BigDecimal.valueOf(20.00) is that following the rules of BigDecimal.valueOf(double), this results in a BigDecimal of 20.0 (that is, scale 1), and - slightly different - new BigDecimal(20.00) will result in a BigDecimal of 20 (scale 0).

Upvotes: 11

GhostCat
GhostCat

Reputation: 140525

Besides the technical new BigDecimal("20.00") isn't the same as new BigDecimal(20.00) (because of the "" which trigger "string parsing"), I suggest you look into hamcrest.

That framework even offers BigDecimalCloseTo when you need to test "equality + delta", to be used like:

assertThat(new BigDecimal("1.03"), is(closeTo(new BigDecimal("1.0"), new BigDecimal("0.03"))))

Upvotes: 3

Related Questions