Это появляется это CollectionAssert
не может использоваться с дженериками. Это супер печально; код, который я хочу протестировать, действительно использует дженерики. Что я должен сделать? Записать шаблон для преобразования между двумя? Вручную проверьте эквивалентность набора?
Это перестало работать:
ICollection<IDictionary<string, string>> expected = // ...
IEnumerable<IDictionary<string, string>> actual = // ...
// error 1 and 2 here
CollectionAssert.AreEqual(expected.GetEnumerator().ToList(), actual.ToList());
// error 3 here
Assert.IsTrue(expected.GetEnumerator().SequenceEquals(actual));
Ошибки компилятора:
Ошибка 1:
'Система. Наборы. Универсальный. IEnumerator>' не содержит определение для 'ToList' и никакой дополнительный метод 'ToList', принимающий первый аргумент типа 'Система. Наборы. Универсальный. IEnumerator>' мог быть найден
Ошибка 2
'Система. Наборы. Универсальный. IEnumerator>' не содержит определение для 'ToList' и никакой дополнительный метод 'ToList', принимающий первый аргумент типа 'Система. Наборы. Универсальный. IEnumerator>' мог быть найден
Ошибка 3
'Система. Наборы. Универсальный. IEnumerator>' не содержит определение для 'SequenceEquals' и никакой дополнительный метод 'SequenceEquals', принимающий первый аргумент типа 'Система. Наборы. Универсальный. IEnumerator>' мог быть найден
Что я делаю неправильно? Разве я не использую расширения правильно?
Обновление: хорошо, это выглядит немного лучше, но все еще не работает:
IEnumerable<IDictionary<string, string>> expected = // ...
IEnumerable<IDictionary<string, string>> actual = // ...
CollectionAssert.AreEquivalent(expected.ToList(), actual.ToList()); // fails
CollectionAssert.IsSubsetOf(expected.ToList(), actual.ToList()); // fails
Я не хочу сравнивать списки; я только забочусь о равенстве членства в наборе. Порядок участников неважен. Как я могу обойти это?
Вы можете легко написать свою собственную универсальную версию, а затем переместить ее в базовый или служебный класс, который будет использоваться во всех ваших тестах. Основывайте его на операторах LINQ, таких как All и Any.
Вы можете использовать CollectionAssert
с универсальными коллекциями. Уловка состоит в том, чтобы понять, что методы CollectionAssert
работают с ICollection
, и хотя несколько универсальных интерфейсов сбора реализуют ICollection
, List
делает.
Таким образом, вы можете обойти это ограничение, используя метод расширения ToList
:
IEnumerable<Foo> expected = //...
IEnumerable<Foo> actual = //...
CollectionAssert.AreEqual(expected.ToList(), actual.ToList());
Тем не менее, я все еще считаю, что CollectionAssert
сломан во многих других отношениях , поэтому я предпочитаю использовать Assert.IsTrue (bool)
с методами расширения LINQ, например:
Assert.IsTrue(expected.SequenceEqual(actual));
FWIW, в настоящее время я использую эти методы расширения для выполнения других сравнений:
public static class EnumerableExtension
{
public static bool IsEquivalentTo(this IEnumerable first, IEnumerable second)
{
var secondList = second.Cast<object>().ToList();
foreach (var item in first)
{
var index = secondList.FindIndex(item.Equals);
if (index < 0)
{
return false;
}
secondList.RemoveAt(index);
}
return secondList.Count == 0;
}
public static bool IsSubsetOf(this IEnumerable first, IEnumerable second)
{
var secondList = second.Cast<object>().ToList();
foreach (var item in first)
{
var index = secondList.FindIndex(item.Equals);
if (index < 0)
{
return false;
}
secondList.RemoveAt(index);
}
return true;
}
}