【问题标题】:Decoded circe array inside case class always failing case class comparison test?案例类中解码的circe数组总是失败案例类比较测试?
【发布时间】:2019-06-05 09:16:34
【问题描述】:

对于这个案例类:

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 to case class test)

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 中有更多的东西,我在这个例子中遗漏了 - 地图和嵌套的案例类都被解码并且可以比较,只有当数组是补充说比较失败 - 我错过了什么吗?

【问题讨论】:

  • 这不是您应该比较数组的方式。只需比较数组中的元素。并使用equals 比较这些字符串。

标签: scala circe


【解决方案1】:

这更像是 Scala 问题(或 ScalaTest 问题),而不是 circe 问题。 Scala 在数组上的== 方法使用引用相等,而ScalaTest 的shouldEqual 将在数组上“正确”工作(即它会比较内容而不是引用),但在比较两种情况时,它仍将== 用于数组成员类实例。

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

【讨论】:

  • 谢谢,在案例类中将 Array 更改为 List 对我有用。
猜你喜欢
  • 2019-03-15
  • 1970-01-01
  • 2019-03-13
  • 1970-01-01
  • 2021-03-08
  • 2018-10-22
  • 1970-01-01
  • 2018-05-03
  • 2020-05-16
相关资源
最近更新 更多