我正在尝试对一些非常集合的Scala进行单元测试。这些集合以Iterable[T]
的形式返回,因此我对集合的内容感兴趣,即使基础类型不同也是如此。这实际上是两个相关的问题:
总之,我在ScalaTest中看到Scala相当于NUnit的CollectionAssert.AreEqual
(有序)和CollectionAssert.AreEquivalent
(无序):
Set(1, 2) should equal (List(1, 2)) // ordered, pass
Iterable(2, 1) should equal (Iterable(1, 2)) // unordered, pass
答案 0 :(得分:83)
同时你可以使用
Iterable(2, 1) should contain theSameElementsAs Iterable(1, 2)
要测试有序集,您必须将其转换为序列。
Set(1, 2).toSeq should contain theSameElementsInOrderAs List(1, 2)
答案 1 :(得分:20)
您可以针对有序集合尝试.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)) }
}
BTW Set
未订购。
修改:为避免删除重复元素,请尝试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)
}
e.g。 (注意使用没有定义顺序的符号'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)
}