case class 内的解码 circe 数组总是失败 case class 比较测试?

Decoded circe array inside case class always failing case class comparison test?

对于这种情况class:

import io.circe.generic.JsonCodec

@JsonCodec
case class Stuff(things: Array[String])

此测试通过(案例 class 到 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 到案例 class 测试)

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

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

[Ljava.lang.String;@2fa7ae9

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

这更像是一个 Scala 问题(或 ScalaTest 问题),而不是循环问题。 Scala 在数组上的 == 方法使用引用相等性,而 ScalaTest 的 shouldEqual 将在数组上工作 "correctly" (即它会比较内容而不是引用),它仍然会使用 == 比较两个 case class 实例时的数组成员。

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