Comparing collection contents with ScalaTest

后端 未结 2 631
予麋鹿
予麋鹿 2020-12-24 10:59

I\'m trying to unit-test some Scala that is very collection-heavy. These collections are returned as Iterable[T], so I am interested in the contents of

相关标签:
2条回答
  • 2020-12-24 11:28

    You could try .toSeq for ordered collections and .toSet for unordered, which captures what you want as far as I understand it.

    The following passes:

    class Temp extends FunSuite with ShouldMatchers {
      test("1")  { Array(1, 2).toSeq should equal (List(1, 2).toSeq) }
      test("2")  { Array(2, 1).toSeq should not equal (List(1, 2).toSeq) }
      test("2b") { Array(2, 1) should not equal (List(1, 2)) }  
      test("3")  { Iterable(2, 1).toSet should equal (Iterable(1, 2).toSet) }
      test("4")  { Iterable(2, 1) should not equal (Iterable(1, 2)) }
    }
    

    BTW a Set is not ordered.

    edit: To avoid removing duplicate elements, try toSeq.sorted. The following pass:

      test("5")  { Iterable(2, 1).toSeq.sorted should equal (Iterable(1, 2).toSeq.sorted) }
      test("6")  { Iterable(2, 1).toSeq should not equal (Iterable(1, 2).toSeq) }
    

    edit 2: For unordered collections where elements cannot be sorted, you can use this method:

      def sameAs[A](c: Traversable[A], d: Traversable[A]): Boolean = 
        if (c.isEmpty) d.isEmpty
        else {
          val (e, f) = d span (c.head !=)
          if (f.isEmpty) false else sameAs(c.tail, e ++ f.tail)
        }
    

    e.g. (note use of symbols 'a 'b 'c which have no defined ordering)

      test("7")  { assert( sameAs(Iterable(2, 1),    Iterable(1, 2)     )) }
      test("8")  { assert( sameAs(Array('a, 'c, 'b), List('c, 'a, 'b)   )) }
      test("9")  { assert( sameAs("cba",             Set('a', 'b', 'c') )) }
    

    Alternative sameAs implementation:

      def sameAs[A](c: Traversable[A], d: Traversable[A]) = {
        def counts(e: Traversable[A]) = e groupBy identity mapValues (_.size)
        counts(c) == counts(d)
      }
    
    0 讨论(0)
  • 2020-12-24 11:40

    Meanwhile you can use

    Iterable(2, 1) should contain theSameElementsAs Iterable(1, 2)
    

    To test the ordered set you have to convert it to a sequence.

    Set(1, 2).toSeq should contain theSameElementsInOrderAs List(1, 2)
    
    0 讨论(0)
提交回复
热议问题