【问题标题】:Equality of Scala case class does not work in junit assertEquals when it contains an inner ArrayScala案例类的相等性在包含内部数组时在junit assertEquals 中不起作用
【发布时间】:2020-03-11 16:00:53
【问题描述】:

我在 scala 中有一个 case class foo(a: Array[String], b: Map[String,Any]) 我正在尝试为此运行单元测试,但 assertEquals 同时将 foo 元素(实际和预期)存储在数组中。 所以最后一行是使用assertEquals(expected.deep, actual.deep)

地图 b 显示正确,但 assertEquals 尝试匹配数组 a 的哈希码而不是内容。错误是 get 是这样的: Array(foo([Ljava.lang.string@235543a70,Map("bar" -> "bar")))

整体代码看起来像

  case class Foo(a: Array[String], b: Map[String, Any])

  val foo = Foo(Array("1"), Map("ss" -> 1))
  val foo2 = Foo(Array("1"), Map("ss" -> 1))

  org.junit.Assert.assertEquals(Array(foo).deep, Array(foo2).deep)

您建议如何进行这项工作?

【问题讨论】:

  • Java 数组未正确实现相等检查。请改用Seq

标签: scala junit equals equality case-class


【解决方案1】:

scala 中的案例类带有自己的 hashCodeequals 方法,它们不应被覆盖。此实现检查内容的相等性。但它依赖于案例类中使用的类型的基于“内容”的hashCodeequals 实现。

不幸的是,Arrays 不是这种情况,这意味着使用默认的equals 方法无法通过内容检查数组。

最简单的解决方案是使用基于内容检查相等性的数据集合,例如Seq

  case class Foo(a: Seq[String], b: Map[String, Any])

  val foo = Foo(Seq("1"), Map("ss" -> 1))
  val foo2 = Foo(Seq("1"), Map("ss" -> 1))

  org.junit.Assert.assertEquals(foo, foo2)

在这种情况下调用deep 对您没有帮助,因为它只扫描和转换嵌套的Array

  println(Array(foo, Array("should be converted and printed")))
  println(Array(foo, Array("should be converted and printed")).deep)

产生

[Ljava.lang.Object;@188715b5
Array(Foo([Ljava.lang.String;@6eda5c9,Map(ss -> 1)), Array(should be converted and printed))

【讨论】:

    猜你喜欢
    • 2017-03-21
    • 2015-08-14
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 2019-02-06
    • 2011-09-15
    • 1970-01-01
    • 2014-06-30
    相关资源
    最近更新 更多