Category Archives: Mockito

Mockito and floating point objects like BigDecimal

Last week I saw a Java project which used mockito. Great! Only point of attention was that it used a BigDecimal object as a key / identifier. So:

when(new BigDecimal(11)).thenReturn("test 1");

This runs fine when the BigDecimal does not have a scale (like in the example). It is different story when a scale is added, for example a currency amount.

when(new BigDecimal(11.78)).thenReturn("test 1");

This uses the default matcher, which then will compare (on the equals()) like:

 11.17999999999992888474774 to 11.78

Ergo; the above when with 11.78 will never return a value. To fix this you can use your own matcher. Use the following code for this:

when(argThat(new CurrencyMatcher(new BigDecimal(11.78))).thenReturn("test 1");

And the CurrencyMatcher class will then be as followed.

class CurrencyMatcher extends ArgumentMatcher {
      BigDecimal bigDecimal;

      public CurrencyMatcher(BigDecimal bigDecimal) {
          this.bigDecimal = bigDecimal;
      }

      public boolean matches(Object bigDecimalB) {
          if(bigDecimalB == null && bigDecimal != null) {
              return false;
          }

          if(bigDecimalB == null && bigDecimal == null) {
              return true;
          }

          NumberFormat eurCostFormat = NumberFormat.getCurrencyInstance(Locale.NL);
          return eurCostFormat.format(bigDecimal).equals(eurCostFormat.format(bigDecimalB);
      }