[英]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.