1

I have a case class like this.

case class A(a: Int, List[Int])

Now I want to assert two instances of A

val a = A(100, List(2, 4))
val b = A(100, List(4, 2))

a shouldBe b 
a shouldEqual b

Above two statements fail because List(2, 4) does not have same order as List(4, 2).

Is there a way to assert whole objects of A i.e. a and b, so that it passes ?

user9920500
  • 606
  • 7
  • 21

2 Answers2

3

Using the Inside mixing you can do something like:

class Spec extends FlatSpec with Matchers with Inside {
  it should "be equal regarding order" in {
    val result = A(100, List(2, 4))

    inside(result) {
      case A(a, list) =>
       a shouldBe 100
       list should contain theSameElementsAs List(4, 2)
    }
  }
}
1

Consider defining custom equality like so

case class A(a: Int, l: List[Int])
object A {
  implicit val aEq: Equality[A] = (a: A, b: Any) => b match {
    case bb: A => bb.a == a.a && bb.l.sorted == a.l.sorted
    case _ => false
  }
}

class ExampleSpec extends FlatSpec with Matchers {
  "As" should "be equal ignoring the order of elements in lists" in {
    val aa = A(100, List(2, 4))
    val bb = A(100, List(4, 2))

    aa should equal (bb)
  }
}

or matchPattern like so

"As" should "be equal ignoring the order of elements in lists" in {
  case class A(a: Int, l: List[Int])
  val aa = A(100, List(2, 4))
  val bb = A(100, List(4, 3))

  aa should matchPattern { case A(a, l) if bb.a == a && bb.l.sorted == l.sorted => }
}
Mario Galic
  • 47,285
  • 6
  • 56
  • 98