Есть ли простой способ войти? xunit.net сравнить две коллекции без учета заказа предметов?
в одном из моих тестов, я хочу убедиться, что сборник имеет определенные элементы. Поэтому я хочу сравнить эту коллекцию с элементами ожидаемой коллекции не относительно порядка пунктов. В настоящее время, мой тестовый код выглядит так:
[Fact]
public void SomeTest()
{
// Do something in Arrange and Act phase to obtain a collection
List<int> actual = ...
// Now the important stuff in the Assert phase
var expected = new List<int> { 42, 87, 30 };
Assert.Equal(expected.Count, actual.Count);
foreach (var item in actual)
Assert.True(expected.Contains(item));
}
есть ли более простой способ достичь этого в xunit.net? Я не могу использовать Assert.Equal
поскольку этот метод проверяет, является ли порядок элементов одинаковым в обеих коллекциях. Я взглянул на Assert.Collection
но это не удаляет Assert.Equal(expected.Count, actual.Count)
оператор в коде выше.
Спасибо за ваши ответы заранее.
4 ответов
Брэд Уилсон из xunit.net сказал мне в этом Выпуск Github что нужно использовать LINQ это OrderBy
оператора, а потом Assert.Equal
чтобы убедиться, что две коллекции содержат равные элементы без учета их порядка. Конечно, у вас должно быть свойство в соответствующем классе элементов, которое вы можете использовать для заказа в первую очередь (чего у меня на самом деле не было в моем случае).
лично я решил эту проблему с помощью FluentAssertions, a библиотека, которая предоставляет множество методов утверждения, которые могут быть применены в беглом стиле. Конечно,есть также много методов, которые можно использовать для проверки коллекции.
в контексте моего вопроса я бы использовал что-то вроде следующего кода:
[Fact]
public void Foo()
{
var first = new[] { 1, 2, 3 };
var second = new[] { 3, 2, 1 };
first.Should().BeEquivalentTo(second);
}
этот тест проходит, потому что BeEquivalentTo
вызов игнорирует порядок элементов.
Shouldly также является хорошей альтернативой, если вы не хотите идти с FluentAssertions.
не Xunit, а ответ Linq:
bool areSame = !expected.Except(actual).Any() && expected.Count == actual.Count;
Так в XUnit:
Assert.True(!expected.Except(actual).Any() && expected.Count == actual.Count));
как сказал @robi-y, в Microsoft.VisualStudio.QualityTools.UnitTestFramework
здесь CollectionAssert.AreEquivalent
может быть, другой способ:
Assert.True(expected.SequenceEqual(actual));
Это тоже проверяет порядок. Вот что происходит внутри :
using (IEnumerator<TSource> e1 = first.GetEnumerator())
using (IEnumerator<TSource> e2 = second.GetEnumerator())
{
while (e1.MoveNext())
{
if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current))) return false;
}
if (e2.MoveNext()) return false;
}
return true;
Так что если вы не заботитесь о порядке, просто заказать оба списка до
Assert.True(expected.OrderBy(i => i).SequenceEqual(actual.OrderBy(i => i)));
можно использовать CollectionAssert.AreEquivalent
С Microsoft
CollectionAssert.AreEquivalent(expected, actual);