xUnit: утверждать, что два списка <T> равны?

109

Я новичок в TDD и xUnit, поэтому хочу протестировать свой метод, который выглядит примерно так:

List<T> DeleteElements<T>(this List<T> a, List<T> b);

Есть ли какой-нибудь метод Assert, который я могу использовать? Я думаю что-то подобное было бы неплохо

List<int> values = new List<int>() { 1, 2, 3 };
List<int> expected = new List<int>() { 1 };
List<int> actual = values.DeleteElements(new List<int>() { 2, 3 });

Assert.Exact(expected, actual);

Есть что-то подобное?

Петр Петров
источник

Ответы:

137

xUnit.Net распознает коллекции, поэтому вам просто нужно сделать

Assert.Equal(expected, actual); // Order is important

Вы можете увидеть другие доступные утверждения коллекции в CollectionAsserts.cs

Для коллекции библиотеки NUnit методы сравнения:

CollectionAssert.AreEqual(IEnumerable, IEnumerable) // For sequences, order matters

и

CollectionAssert.AreEquivalent(IEnumerable, IEnumerable) // For sets, order doesn't matter

Подробнее здесь: CollectionAssert

MbUnit также имеет утверждения коллекции, аналогичные NUnit: Assert.Collections.cs

Константин Спирин
источник
1
Ссылка на исходный код изменена для xunit.codeplex.com/SourceControl/changeset/view/…
Жюльен
1
Новая ссылка в комментариях тоже не работает.
Скотт Стаффорд
1
Проект теперь перемещен на GitHub, но мне также не удалось найти там этот конкретный исходный файл.
MEMark
1
Для сложного объекта не забывайте, что вам нужен Equal + GetHasCode, чтобы это работало, или дайте методу Equal собственный EqulityComparer
maracuja-juice
2
Метод xUnit Equal возвращает false для двух IEnumerables с одинаковым содержимым.
Владимир Кочянчич
31

В текущей версии XUnit (1.5) вы можете просто использовать

Assert.Equal (ожидаемый, фактический);

Вышеупомянутый метод будет выполнять сравнение элементов двух списков. Я не уверен, работает ли это с какой-либо предыдущей версией.

Hwiechers
источник
8
Проблема, с которой я столкнулся с Assert.Equal для коллекций, заключается в том, что он не работает, если элементы коллекций находятся в разном порядке, даже если элементы присутствуют в обоих.
Скотт Лоуренс
1
@ ScottA.Lawrence В списках тоже порядок! У вас такое же поведение с HashSets?
johv
@johv Я не тестировал его с HashSets, но это хорошая идея. Как только у меня будет возможность попробовать, я постараюсь не забыть ответить здесь.
Скотт Лоуренс
2
Также кажется, что это не удается, если типы коллекций различаются, даже если они оба содержат одинаковые элементы в одном порядке.
Джеймс Уайт,
3
Но у него очень дерьмовый вывод. Он не говорит вам, ГДЕ два списка различаются! :(
Zordid
17

С xUnit, если вы хотите выбрать свойства каждого элемента для тестирования, вы можете использовать Assert.Collection.

Assert.Collection(elements, 
  elem1 => Assert.Equal(expect1, elem1.SomeProperty),
  elem2 => { 
     Assert.Equal(expect2, elem2.SomeProperty);
     Assert.True(elem2.TrueProperty);
  });

Это проверяет ожидаемое количество и гарантирует, что каждое действие проверено.

Дрю Уильямс
источник
2

Недавно я использовал xUnit 2.4.0и Moq 4.10.1пакеты в моем asp.net ядре 2.2 приложения.

В моем случае мне удалось заставить его работать в два этапа:

  1. Определение реализации IEqualityComparer<T>

  2. Передайте экземпляр компаратора в качестве третьего параметра в Assert.Trueметод:

    Assert.True(expected, actual, new MyEqualityComparer());

Но есть еще один более приятный способ получить тот же результат с помощью пакета FluentAssertions . Это позволяет делать следующее:

// Assert          
expected.Should().BeEquivalentTo(actual));

Интересно, что это Assert.Equal()всегда терпит неудачу, даже когда я заказывал элементы двух списков, чтобы они располагались в одном порядке.

Дмитрий Степанов
источник
2
что-то не так с вашим порядком. BeEquivalentTo не заботится о порядке (вот почему ваш тест проходит с BeEquivalentTo, а не с assert.Equal)
RagnaRock