Confusion over REST Guaranteed floating point comparisons

The documentation for using REST Assured has the following examples:

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

OK, so they use Hamcrest match to compare with int 5 value.

But they have a section that says the REST Assured JSON agent uses float by default, not double , so instead of comparing with 12.12 I have to compare with 12.12f :

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

Wait, how does 5 work higher than int and not double ? Does the JSON parser use different primitives for integer and non-integer values?

But it gets more confusing. Sure programmers know that you should not compare floating point values ​​in any case (due to the intricacies of storing floating point values, etc.). Instead, you should use Matchers.closeTo(double operand, double error) , which provides an error. This is the right way to do this. But wait, even if I 12.12f to Matchers.closeTo (double operand, double error) at 12.12f , is it still going to convert it to double ? Will this work with REST Assured?

+5
source share
4 answers

I am not 100% sure that I am right here, but this post has become too long for comment ...

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

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

Thus, since REST Assured represents floating point values ​​as a float, and Double.equals can only return true if this other object is Double , you must use a float , not Double (since the input will be placed in the object).

In addition, the floats section in REST Assured documents indicates that it applies only to floating point values:

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

I assume that this means that integers are correctly represented as integers. (Other examples in the docs also seem to suggest this)

If you decide to use Matchers.closeTo instead of equalTo or is (which itself calls equalTo ), then it doesn't matter if you use Double or float .

+1
source

You can compare a lot of things with equalTo hamcrest.Matchers, it also used for approval in the test:

 assertThat(longValue, equalTo(10L)); assertThat(cadena, equalTo("Esta es una cadena")); 

There is a comparison with Long and String, and of course you have closeTo to compare things like doubling or bigdecimal, look here and there

Indeed, this is normal, but you can also compare or make equal when convenient

0
source

It looks like you are mixing two things together.

Does the JSON parser use different primitives for integer and non-integer values?

Comparison of values ​​is performed using the specified metric object. This match has no effect on Json Parser. No matter what value you assign to the match ( 5 in the first example) and what value will be returned by the jsonpath, the match is ( org.hamcrest.core.IsEqual ) compares both values ​​by calling the Objects.equals () method. Json parser also works with object values, not primitives.

so how did 5 work, which is int and not double?

Assuming JsonPath lotto.lottoId will return an int value, thus body("lotto.lottoId", equalTo(5)); will be true (obviously json should be 5 )

12.2' and 12.2f' are treated as the same values ​​in your example. The suffix 'f' in your example is redundant and has no effect. Since the closeTo(double, double) method defined argument types as double, the passed float values ​​would get an implicit advance to double types.

Since you know that the json value will be double, you can express your statement as:

 get("/price").then().body("price", closeTo(12.12, 0.01)); 

Depending on the configuration of the Json parser, a non-integer value may be read as BigDecimal. If so, you can use variance closeTo() as

 .get("/price").then().body("price", closeTo(BigDecimal.valueOf(12.12), BigDecimal.valueOf(0.01))) 

Hope this helps.

0
source

If you carefully read Hamcrest , you will find that it is clearly stated " when the object being investigated is logically equal to the specified operand " for equalTo . So it’s obvious that it doesn’t matter if it is “5” or 5! ANd in Rest-Assured . Mentioned that equalTo and hasItems are Hamcrest combinations that you should statically import from org.hamcrest.Matchers. So I don’t think there should be any confusion.

0
source

Source: https://habr.com/ru/post/1272729/


All Articles