REST Assured浮点数比较引起的困惑

7
REST Assured使用文档中有这样的示例:

使用文档 像这样:

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

好的,他们使用Hamcrest matcher来与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 传递给 Matchers.closeTo(double operand, double error),它是否仍然会将其转换为 double?这个方法能够在 REST Assured 中使用吗?

4个回答

3

我不完全确定我的理解是否正确,但这篇文章太长了,无法作为评论。

从阅读HamcrestREST Assured的文档中得知,equalTo只在被测对象调用Object.equals方法时返回true:

[equalTo] 创建一个匹配器来判断被测对象是否逻辑上等于指定操作数,通过调用被测对象的Object.equals(java.lang.Object)方法来确定。

因此,由于REST Assured将浮点值表示为浮点数,而Double.equals仅在其他对象为Double时才能返回true,因此需要使用float而不是double(因为输入将封装为对象)。

此外,REST Assured文档中的浮点数部分似乎表明它仅适用于浮点数值:

浮点数必须使用Java的"float"原始类型进行比较。

我认为这意味着整数以Integer形式正确表示。(文档中的其他示例似乎也表明了这一点)

如果您选择使用Matchers.closeTo而不是equalTois(它本身调用equalTo),那么使用doublefloat都无所谓。


你的回答最接近于真正回答了我的问题,尽管你的一些答案不够权威。你提出的最重要的观点是,如果我使用Matcher.closeTo()(这也是我们应该使用的),那么JSON解析器输出什么可能并不重要。 - Garret Wilson

0
如果您仔细阅读Hamcrest,您会发现,对于equalTo,它清楚地说明了“当被检查的对象在逻辑上等于指定的操作数时”。所以显然,它不重要是“5”还是5!而且在Rest-Assured中,提到equalTo和hasItems是Hamcrest匹配器,您应该从org.hamcrest.Matchers静态导入。因此,我认为不应该有任何困惑。

0

您可以使用hamcrest.Matchers的equalTo来比较很多东西,它也用于测试中的断言:

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

有一个比较长整型和字符串的比较,当然,你也可以使用closeTo来比较double或bigdecimal之类的东西,看一下这里那里

因此,确实会感到惊讶,但你也可以选择在方便时进行比较或相等操作。


0

看起来你把两件事情混在一起了。

JSON解析器是否使用不同的原语来表示整数和非整数值?

值比较是由给定的匹配器对象完成的。给定的匹配器不会以任何方式影响Json解析器。无论您将什么值赋给匹配器(例如第一个示例中的5),以及给定的jsonpath将返回什么值,equals匹配器(org.hamcrest.core.IsEqual)都会通过调用Objects.equals()方法来比较这两个值。此外,Json解析器使用值对象而不是基本类型。

那么上面的5是如何工作的,它是int而不是double?

假设JsonPath lotto.lottoId将返回int值,因此body("lotto.lottoId", equalTo(5));将为true(显然json值必须为5)。

12.2'和12.2f'在您的示例中被视为相同的值。在您的示例中添加'f'后缀是多余的且没有效果。由于方法closeTo(double, double)已将参数类型定义为double,传递的float值会隐式地提升为double类型。

既然您知道json的值将是double,因此您可以将断言表达为:

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)))

希望能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接