案例类内部的解码Circe数组始终无法通过案例类比较测试?

时间:2019-01-10 13:28:35

标签: scala circe

对于此案例类:

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中的许多内容-Maps和嵌套的case类都被解码了,可以进行比较,只有当Arrays被补充说,比较失败-我错过了什么吗?

1 个答案:

答案 0 :(得分:5)

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

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