[英]Confusion over REST Assured floating-point comparisons
REST Assured 使用文檔包含以下示例:
get("/lotto").then().body("lotto.lottoId", equalTo(5));
好的,所以他們使用Hamcrest匹配器來比較int值5
。
但他們有一節說默認使用REST Assured JSON解析器使用float
而不是double
,所以不應該比較12.12
我應該比較12.12f
:
get("/price").then().body("price", is(12.12f));
等等,所以上面有5
工作,這是一個int
而不是double
? JSON解析器是否對整數和非整數值使用不同的基元?
但它變得更加混亂。 精通程序員知道你不應該直接比較浮點值(因為存儲浮點值的方法很復雜等)。 相反,你應該使用Matchers.closeTo(double operand, double error)
,它提供了一個誤差范圍。 這是正確的方法。 但是等等---即使我將12.12f
傳遞給12.12f
(雙操作數,雙錯誤),是不是仍然要將它轉換為double
? 這可以與REST保證一起使用嗎?
我不是百分百肯定我在這里是對的,但是這個帖子對於評論來說太長了...
通過閱讀Hamcrest和REST Assured的文檔,看起來equalTo
只在Object.equals
返回true的情況下返回true:
[equalTo]創建一個匹配器,匹配當被檢查對象在邏輯上等於指定的操作數時,通過在被檢查對象上調用Object.equals(java.lang.Object)方法來確定。
因此,由於REST Assured將浮點值表示為浮點數,而Double.equals
只能返回true
如果其他對象是Double
,則必須使用float
而不是double
(因為輸入將被裝入對象)。
此外,REST Assured文檔中的浮動部分似乎表明它僅適用於浮點值:
必須將浮點數與Java“float”原語進行比較。
我認為這意味着整數被正確地表示為整數。 (文檔中的其他示例似乎也暗示了這一點)
如果您選擇使用Matchers.closeTo
而不是equalTo
或者is
(這本身調用equalTo
),那么它不應該,如果你使用的事double
或float
。
看起來你把兩件事混在一起。
JSON解析器是否對整數和非整數值使用不同的基元?
值比較由給定的匹配器對象完成。 無論如何,給定的匹配器對Json Parser沒有任何影響。 無論您給匹配器(第一個示例中為5
)賦予什么值以及給定的jsonpath返回什么值,等於匹配器( org.hamcrest.core.IsEqual
)通過調用Objects.equals()方法來比較兩個值。 Json解析器也可以使用值對象而不使用基元。
那么5如何在上面工作,這是一個int而不是一個雙?
假設JsonPath lotto.lottoId
將返回int值,因此body("lotto.lottoId", equalTo(5));
將是真的(顯然json值必須是5
)
在您的示例中, 12.2' and
12.2f'被視為相同的值。 你的例子中的后綴“f”是多余的,沒有任何效果。 由於closeTo(double, double)
方法closeTo(double, double)
參數類型定義為double,因此傳遞的float值將隱式提升為double類型。
既然你知道你的json的值會加倍,那么你可以將你的斷言表達為:
get("/price").then().body("price", closeTo(12.12, 0.01));
根據Json解析器配置,非整數值可以讀取為BigDecimal,如果是這種情況,則可以使用closeTo()
方差作為
.get("/price").then().body("price",
closeTo(BigDecimal.valueOf(12.12), BigDecimal.valueOf(0.01)))
希望能幫助到你。
如果您仔細閱讀Hamcrest,那么您會發現, 當被檢查對象在邏輯上等於指定的操作數時 ,它會被明確說明為equalTo 。 所以顯然它是“5”還是5並不重要! 在Rest-Assured中提到,提到equalTo和hasItems是Hamcrest匹配器,你應該從org.hamcrest.Matchers靜態導入。 所以我認為不應該有任何混淆。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.