Чтобы понять, что происходит, нам нужно понять, что на самом деле делает Assert.Equal()
. Согласно документации Assert.Equal<T>(IEnumerable<T> expected, IEnumerable<T> actual)
он «Проверяет, что две последовательности эквивалентны, используя компаратор по умолчанию».
Assert.Equal()
в этом случае перебирает перечисляемое значение, чтобы проверить, равны ли отдельные значения. Это означает, что перечисляемое значение повторяется дважды для сравнения, и каждый раз создается новый экземпляр ReferenceType
(с помощью возврата доходности). Тест не пройден, поскольку компаратор по умолчанию для ссылочного типа только проверяет, ссылаются ли экземпляры на один и тот же объект.
Есть как минимум три способа получить ожидаемый результат:
- Используйте перегрузку для
Assert.Equal()
, которая принимает аргумент IEqualityComparer<T>
.
- Переопределить
Equals()
метод ReferenceType
.
- Пропустите
yield return
и используйте коллекцию, которая реализует IEnumerable
.
Возможно, первое решение является лучшим, поскольку оно не меняет реализацию GetEnumerable()
или ReferenceType
. В этом случае, когда GetEnumerable()
используется только в тесте, я бы выбрал третий вариант, так как он самый простой. Это может выглядеть примерно так:
IEnumerable<ReferenceType> GetData()
{
return new[] { new ReferenceType() };
}
или это:
IEnumerable<ReferenceType> GetData()
{
var referenceTypes = new List<ReferenceType>();
// ... add reference types
return referenceTypes;
}
Это работает, так как теперь мы выполняем итерацию коллекции, которая была создана, когда мы получили перечисляемый объект, и не создаем новый экземпляр для каждой итерации.