Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion over REST Assured floating-point comparisons

The REST Assured usage documentation has examples like this:

get("/lotto").then().body("lotto.lottoId", equalTo(5));

OK, so they are using a Hamcrest matcher to compare to the int value 5.

But they have a section saying that the REST Assured JSON parser by default uses float and not double, so instead of comparing to 12.12 I should compare to 12.12f:

get("/price").then().body("price", is(12.12f));

Wait, so how did 5 work above, which is an int and not a double? Does the JSON parser use different primitives for integer and non-integer values?

But it gets more confusing. Well-versed programmers know that you shouldn't be comparing floating point values directly anyway (because of the intricacies of how floating-point values are stored, etc.). Instead you should use Matchers.closeTo(double operand, double error) which provides a margin of error. This is the correct way to do it. But wait --- even if I pass in 12.12f to Matchers.closeTo(double operand, double error), isn't it still going to convert it to a double? Will this work with REST Assured?

like image 585
Garret Wilson Avatar asked Oct 18 '17 16:10

Garret Wilson


Video Answer


1 Answers

I'm not 100% sure I'm correct here, but this post became too long for a comment...

From reading the docs for Hamcrest and REST Assured it seems like equalTo only returns true in the cases that Object.equals returns true:

[equalTo] Creates a matcher that matches when the examined object is logically equal to the specified operand, as determined by calling the Object.equals(java.lang.Object) method on the examined object.

Thus since REST Assured represents floating point values as floats, and Double.equals can only return true if that other object is a Double, it is necessary to use a float and not a double (as the input will get boxed into an object).

Also, the section of floats in the REST Assured docs seems to indicate it only applies to floating point values:

Floating point numbers must be compared with a Java "float" primitive.

I presume that means that integers are represented properly as Integers. (Other examples in the docs also seems to suggest this)

If you chose to use Matchers.closeTo instead of equalTo or is (which itself calls equalTo), then it shouldn't matter if you use a double or a float.

like image 168
Spaceman1701 Avatar answered Sep 30 '22 09:09

Spaceman1701