在UNit测试中比较两个ArrayLists

Pas*_*rni 2 c# unit-testing arraylist

我写了一个单元测试,我想比较两个ArrayLists.我确信这两个列表是相同的,测试应该通过,但他没有.

我将它们比作如下:

CollectionAssert.AreEqual(expected, actual)
Run Code Online (Sandbox Code Playgroud)

expected并且actual是这两个ArrayLists.

ArrayLists我上面写的可以比较两个吗?

Mat*_*son 5

这里的问题是CollectionAssert.AreEqual()将使用的元素进行比较Equals().

对于不覆盖的引用类型,Equals()将进行引用比较.这不是你想要的.

幸运的是,你可以解决这个问题,因为它CollectionAssert.AreEqual()有一个允许你指定比较器的重载.

因此,您需要做的就是创建一个比较器,如果两个元素相等则返回零,如果不相等则返回非零.由于ArrayList存储对象这一事实,这有点复杂,因此您需要转换为正确的类型以进行比较.

(请注意,这有点滥用,IComparer因为它应该返回-ve,0或+ ve来提供左侧和右侧的有序比较.但是,CollectionAssert.AreEqual() 仅使用它来测试相等性,所以它就足够了我们在实施中返回零或非零.

AreEqual()理想情况下,该方法使用a IEqualityComparer<T> 来比较元素,但我认为这是后期,AreEqual()所以在AreEqual()编写时它不可用.)

假设您的元素是类型string[](您说它们是),那么您可以创建一个比较器来比较元素,如下所示:

var comparer = Comparer<object>.Create((a, b) => ((string[]) a).SequenceEqual((string[]) b) ? 0 : 1);
Run Code Online (Sandbox Code Playgroud)

然后你可以通过那个比较器AreEqual().

一个例子可以说明这一点:

ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();

list1.Add(Enumerable.Range( 0, 10).Select(n => n.ToString()).ToArray());
list1.Add(Enumerable.Range(10, 10).Select(n => n.ToString()).ToArray());
list1.Add(Enumerable.Range(20, 10).Select(n => n.ToString()).ToArray());

list2.Add(Enumerable.Range( 0, 10).Select(n => n.ToString()).ToArray());
list2.Add(Enumerable.Range(10, 10).Select(n => n.ToString()).ToArray());
list2.Add(Enumerable.Range(20, 10).Select(n => n.ToString()).ToArray());

var comparer = Comparer<object>.Create((a, b) => ((string[]) a).SequenceEqual((string[]) b) ? 0 : 1);
CollectionAssert.AreEqual(list1, list2, comparer);
Run Code Online (Sandbox Code Playgroud)

此断言将成功,但要证明这将检测差异,请将最后一个更改为list2.Add(),list2.Add(Enumerable.Range(20, 9).Select(n => n.ToString()).ToArray());并且断言将失败.