Francislainy Campos
Francislainy Campos

Reputation: 4164

Assert BigDecimal with two trailing zeros using Mockito

I have an api that returns the price for a product with two decimals and that should happen even when these decimals are zero, i.e, 100.00. However, the mockito tests are failing and stripping one of these zeros and I'm not sure why. I have tried to force the scale to have two zeros but that didn't work either, even though the api itself works as expected.

@Test
public void testGetAllProductsOneItemOnlySo() throws Exception {

    UUID productId = UUID.fromString("ac358df7-4a38-4ad0-b070-59adcd57dde0");

    ProductQueryDto productQueryDto = new ProductQueryDto(productId, "product", "prod description", new BigDecimal("100.00").setScale(2, RoundingMode.HALF_UP), null, null);
    List<ProductQueryDto> productQueryDtoList = List.of(productQueryDto);

    when(productQueryService.getAllProducts()).thenReturn(productQueryDtoList);

    RequestBuilder request = MockMvcRequestBuilders
            .get("/api/adverts/product")
            .accept(MediaType.APPLICATION_JSON);
    mockMvc.perform(request).andReturn();

    HashMap<String, Object> result = new HashMap<>();
    result.put("products", productQueryDtoList);

    String json = asJsonString(result);
    mockMvc.perform(request)
            .andExpect(status().is2xxSuccessful())
            .andExpect(content().json(json, true))
            .andExpect(jsonPath("$.products[0].price").value(new BigDecimal("100.00").setScale(2, RoundingMode.HALF_UP)))
            .andReturn();
}

enter image description here

enter image description here

Thank you.

Upvotes: 2

Views: 816

Answers (2)

Francislainy Campos
Francislainy Campos

Reputation: 4164

I just managed to get the tests to pass by setting the big decimal to double.

BigDecimal bg = new BigDecimal("100.00").setScale(2, RoundingMode.HALF_UP);

    String json = asJsonString(result);
    mockMvc.perform(request)
            .andExpect(status().is2xxSuccessful())
            .andExpect(content().json(json, true))
            .andExpect(jsonPath("$.products[0].price").value(bg.doubleValue()))
            .andReturn();

Adding the wikipedia article on which data types are accepted by the json specification: https://en.wikipedia.org/wiki/JSON

enter image description here

Upvotes: 1

Jeff Bowman
Jeff Bowman

Reputation: 95704

The value you're comparing against is a double. JSON can't reasonably contain BigDecimal, as it's not a part of the spec. JSON can contain Number (double) values, which are compared numerically disregarding formatting. There is no reasonable way to represent your 0.00 as a double—the value itself doesn't contain the trailing decimal—so if the decimal points are important you may need to reformat on the client side or reconsider the way you are transporting the information in the first place.

See also: Why not use Double or Float to represent currency?

Upvotes: 1

Related Questions