50

コレクションが非常に多い Scala の単体テストを試みています。これらのコレクションは として返されるため、基になる型が異なっていても、コレクションの内容Iterable[T]に興味があります。これは、実際には 2 つの関連する問題です。

  1. 順序付けられた 2 つのコレクションに同じ要素のシーケンスが含まれていると断言するにはどうすればよいですか?
  2. 順序付けられていない 2 つのコレクションに同じ要素のセットが含まれていると断言するにはどうすればよいですか?

要約すると、ScalaTestで NUnit のCollectionAssert.AreEqual(順序付き) と(順序なし) の Scala に相当するものを探しています。CollectionAssert.AreEquivalent

Set(1, 2) should equal (List(1, 2))          // ordered, pass
Iterable(2, 1) should equal (Iterable(1, 2)) // unordered, pass
4

2 に答える 2

28

.toSeq順序付けられたコレクションと順序付けられていないコレクションを試すことができ.toSetます。これは、私が理解している限り、必要なものをキャプチャします。

次のパス:

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)) }
}

ところでaSetは注文されていません。

編集:重複する要素を削除しないようにするには、 を試してくださいtoSeq.sorted。次のパス:

  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) }

編集 2:要素を並べ替えることができない順序付けられていないコレクションの場合、次の方法を使用できます。

  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)
    }

'a 'b 'c例 (順序が定義されていない記号の使用に注意してください)

  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') )) }

代替sameAs実装:

  def sameAs[A](c: Traversable[A], d: Traversable[A]) = {
    def counts(e: Traversable[A]) = e groupBy identity mapValues (_.size)
    counts(c) == counts(d)
  }
于 2011-09-15T17:48:24.203 に答える