Сравнение содержимого коллекции с ScalaTest - PullRequest
37 голосов
/ 15 сентября 2011

Я пытаюсь провести юнит-тестирование какой-нибудь Scala, которая очень тяжелая для коллекционирования.Эти коллекции возвращаются как Iterable[T], поэтому меня интересует содержимое коллекции, даже если базовые типы различаются.Это на самом деле две взаимосвязанные проблемы:

  1. Как я могу утверждать, что две упорядоченные коллекции содержат одинаковую последовательность элементов?1011 * неупорядоченные коллекции содержат одинаковый набор элементов?

В общем, я ищу Scala-эквивалент NUnit CollectionAssert.AreEqual (упорядоченный) и CollectionAssert.AreEquivalent (неупорядоченный)ScalaTest:

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

Ответы [ 2 ]

83 голосов
/ 16 июня 2014

Тем временем вы можете использовать

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

Для проверки упорядоченного набора необходимо преобразовать его в последовательность.

Set(1, 2).toSeq should contain theSameElementsInOrderAs List(1, 2)
21 голосов
/ 15 сентября 2011

Вы можете попробовать .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)) }
}

Кстати Set не заказано.

edit: Чтобы избежать удаления повторяющихся элементов, попробуйте 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: Для неупорядоченных коллекций, где элементы не могут быть отсортированы, вы можете использовать этот метод:

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