为我的代码编写单元测试时遇到以下问题。为什么将IEnumerable与自身进行比较时Assert.Equal()失败?
private class ReferenceType { }
[Fact]
public void EnumerableEqualityTest()
{
IEnumerable<ReferenceType> GetEnumerable()
{
yield return new ReferenceType();
}
var enumerable = GetEnumerable();
Assert.Equal(enumerable, enumerable); // fails
}
答案 0 :(得分:1)
要了解正在发生的事情,我们需要了解Assert.Equal()
实际在做什么。根据{{1}}的文档,它“使用默认比较器验证两个序列是否相等”。
在这种情况下,Assert.Equal<T>(IEnumerable<T> expected, IEnumerable<T> actual)
迭代枚举,以检查各个值是否相等。这意味着可枚举被迭代两次以进行比较,并且每次(通过yield return)都会创建一个Assert.Equal()
的新实例。测试失败,因为引用类型的默认比较器仅检查实例是否引用同一对象。
至少有三种方法可获得预期结果:
ReferenceType
使用重载,该重载采用Assert.Equal()
的参数。IEqualityComparer<T>
的{{1}}方法。Equals()
,而使用实现ReferenceType
的集合。可以说第一个解决方案是最好的,因为它不会更改yield return
或IEnumerable
的实现。在仅在测试中使用GetEnumerable()
的情况下,我会选择第三个选项,因为它最容易做到。看起来可能像这样:
ReferenceType
或者这个:
GetEnumerable()
之所以可行,是因为我们现在迭代获得枚举时创建的集合,而不是为每次迭代创建新实例。
答案 1 :(得分:0)
我认为,您可以使用以下功能解决问题。
public bool AreEquivalentEnumerator(IEnumerator<TSource> first, IEnumerator<TSource> second)
{
while (first.MoveNext())
{
if (!(second.MoveNext() && Equals(first.Current, second.Current))) return false;
}
if (second.MoveNext()) return false;
return true;
}