对于这种情况类:
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,几乎可以肯定是一个坏主意,但我强烈建议通过将其更改为 List
或 Vector
之类的东西来解决此问题。