scala 比较集合内容与 ScalaTest

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7434762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:28:01  来源:igfitidea点击:

Comparing collection contents with ScalaTest

unit-testingscalascalatest

提问by Michael Koval

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 contentsof the collection, even if the underlying types differ. This is actually two related problems:

我正在尝试对一些非常需要大量收集的 Scala 进行单元测试。这些集合作为 返回Iterable[T],因此我对集合的内容感兴趣,即使基础类型不同。这实际上是两个相关的问题:

  1. How do I assert that two orderedcollections contain the same sequence of elements?
  2. How do I assert that two unorderedcollections contain the same set of elements?
  1. 如何断言两个有序集合包含相同的元素序列?
  2. 如何断言两个无序集合包含相同的元素集?

In summary, I'm looking the Scala-equivalent of NUnit's CollectionAssert.AreEqual(ordered) and CollectionAssert.AreEquivalent(unordered) in ScalaTest:

总之,我正在ScalaTest 中寻找 NUnit 的CollectionAssert.AreEqual(有序)和CollectionAssert.AreEquivalent(无序)的 Scala 等价物:

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

采纳答案by Luigi Plinge

You could try .toSeqfor ordered collections and .toSetfor unordered, which captures what you want as far as I understand it.

您可以尝试.toSeq有序集合和.toSet无序集合,据我所知,它们可以捕获您想要的内容。

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 Setis not ordered.

顺便说一句Set,没有订购。

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

编辑:为避免删除重复元素,请尝试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) }

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

编辑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. (note use of symbols 'a 'b 'cwhich have no defined ordering)

例如(注意使用'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') )) }


Alternative sameAsimplementation:

替代sameAs实现:

  def sameAs[A](c: Traversable[A], d: Traversable[A]) = {
    def counts(e: Traversable[A]) = e groupBy identity mapValues (_.size)
    counts(c) == counts(d)
  }

回答by Christoph Dittberner

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)