2

Test.Hspec.Wai.JSON用来检查我的 api 端点的返回值。我注意到,每当我创建一个值为 的 json 时0.0,当测试运行时,它会将其转换为0(Int),如果 api 返回0.0,则测试失败。

let  j = [json|{"test":0.0}|]
request "GET" "some_url" [("Content-Type", "application/json")] ""
        `shouldRespondWith` j {matchStatus = 200}

   body mismatch:
     expected: {"test":0}  ---> this is the issue (0.0 has become 0)
     but got:  {"test":0.0} 

我在 Haskell 中并没有那么先进,无法找出库代码中发生这种情况的位置。我查看了源代码Test.Hspec.Wai.JSON,它似乎依赖于Aeson.QQ所以不太确定问题的根源。这是Test.Hspec.Wai.JSON 源这是Aeson.QQ 源

因此,我的工作是编写一个FromJSON实例来解析整个响应并检查填写的记录。这有点乏味。

关于库代码中导致此问题的任何建议?以及如何解决?

谢谢,

4

1 回答 1

3

嫌疑人似乎是这一行Data.Aeson.QQ

toExp (JsonNumber n) = [|Number (fromRational $(return $ LitE $ RationalL (toRational n)))|]

它将数字转换为 a Rational,将其转换为 Haskell 表达式,然后将结果表达式转换回 a Number。这最终放弃了它是0.0而不是的事实0

这通常不会成为问题,因为 Aeson 正确定义==为使Number具有相等值的 s 相等。这成为 ; 的实际问题Test.Hspec.Wai.JSON。它的工作方式是将对象编码回 aByteString并期望它完全匹配它。

虽然Data.Aeson.QQ是您问题的根本原因,但我不会责怪它。相反,Test.Hspec.Wai.JSON不应该序列化 JSON 对象并期望它们的表示是等价的。相反,它应该反序列化实际响应并比较解码对象的相等性。(毕竟,浮点/整数不是唯一可能的问题。它也无法处理重新排序的对象键。)我不熟悉 Hspec,所以我不确定你会如何让它这样做。

于 2015-08-16T01:27:02.627 回答