0

It seems that the groovy matcher cannot find an equal float value. What I am exactly doing is ensuring that there is a map with exact values in the response body.

Here is the code

Float purchaseAmount = (Float) ((Map) travelSharedData.bookingPackage.get("total")).get("amount");
response.then().body(String.format("response.cashbacks.find() {it.purchaseAmount.amount == %.2f}", purchaseAmount), is(notNullValue()));

JSON

{
    "response": {
        "cashbacks": [
            {
                "date": "09-08-2017T12:56:39.000Z",
                "purchaseAmount": {
                    "amount": 4963.91,
                    "currency": "USD"
                },
                "cashbackAmount": {
                    "amount": 99.28,
                    "currency": "USD"
                },
                "description": "Tulip House Boutique Hotel Bratislava",
                "estimatedAvailable": "10-28-2017T00:00:00.000Z",
                "status": "pending",
                "eventType": "transaction"
            }
]}}

Error

java.lang.AssertionError: 1 expectation failed.
JSON path response.cashbacks.find() {it.purchaseAmount.amount == 4963.91 && it.description == 'Tulip House Boutique Hotel Bratislava'} doesn't match.
Expected: is not null
  Actual: null

Of course I can convert the values but I would like to know why exactly it fails.

MuchHelping
  • 581
  • 1
  • 4
  • 12
  • 3
    Exact comparisons against floating point numbers are extremely fragile because they are inherently imprecise. That is particularly true for single-precision floats. Try something for me: replace the equality comparison with `it.purchaseAmount.amount > 4963.90 && it.purchaseAmount.amount < 4963.92` and see if you get a result. This will help determine whether it's a floating point issue or a more fundamental issue with your query. – Mike Strobel Sep 08 '17 at 13:23

1 Answers1

0

As @mike-strobel explained it couldn't been found by groovy because float is imprecise by nature.

One workaround is to replace the equality comparison with the next code:

Float purchaseAmount = (Float) ((Map) travelSharedData.bookingPackage.get("total")).get("amount");
Float lowerBound = purchaseAmount - 0.01f;
Float upperBound = purchaseAmount + 0.01f;
response.then().body(String.format("response.cashbacks.find() {it.purchaseAmount.amount > %.2f && it.purchaseAmount.amount < %.2f}", lowerBound, upperBound), is(notNullValue()));

Here's also a good explanation: What's wrong with using == to compare floats in Java?

MuchHelping
  • 581
  • 1
  • 4
  • 12