案例类内的解码环形数组总是未通过案例类比较测试



对于这种情况类:

import io.circe.generic.JsonCodec
@JsonCodec
case class Stuff(things: Array[String])

此测试通过正常(案例类到 json 测试):

import io.circe.parser.decode
import io.circe.syntax._
import org.scalatest._
val caseClass = Stuff(things = Array("one", "two"))
val json = caseClass.asJson.spaces2
json shouldEqual
      """{
         | "things" : [
         |   "one",
         |   "two"
         | ]
         |}""".stripMargin

但是,这是失败的(json到案例类测试)

import io.circe.parser.decode
import io.circe.syntax._
import org.scalatest._
val json =
      """{
         | "things" : [
         |   "one",
         |   "two"
         | ]
         |}""".stripMargin
val caseClass = Right(decode[Stuff](json))
caseClass shouldEqual Stuff(things = Array("one", "two"))

在调试器中逐步执行它,似乎数组没有像我期望的那样被解码,它似乎是对象标识/内存地址,它总是不同的,所以我的测试失败了:

[Ljava.lang.String;@2fa7ae9

请注意,这似乎只是发生在数组中,我的 json blob 中还有很多东西,我在这个例子中遗漏了 - 映射和嵌套案例类都被解码并且可以比较正常,只有当添加数组时,比较才会失败 - 我错过了什么吗?

这更像是一个 Scala 问题(或 ScalaTest 问题),而不是一个 circe 问题。Scala 在数组上的==方法使用引用相等性,虽然 ScalaTest 的shouldEqual在数组上"正确"工作(即它将比较内容而不是引用),但在比较两个案例类实例时,它仍将对数组成员使用 ==

有很多方法可以解决这个问题:为Stuff编写自己的Equality实例,比较caseClass.things shouldEqual Array("one", "two")等。拥有一个可变集合(如 Array)作为案例类成员并不是惯用的 Scala,几乎可以肯定是一个坏主意,但我强烈建议通过将其更改为 ListVector 之类的东西来解决此问题。

最新更新