简体   繁体   English

在UNit测试中比较两个ArrayList

[英]Comparing two ArrayLists in UNit Tests

I wrote a Unit Test, where I want to compare two ArrayLists . 我写了一个单元测试,在这里我想比较两个ArrayLists I am sure these two Lists are equal and the test should pass but he doesn't. 我确信这两个列表是相等的,并且测试应该通过,但他没有通过。

I am comparing them as follow: 我将它们比较如下:

CollectionAssert.AreEqual(expected, actual)

expected and actual are these two ArrayLists . 这两个ArrayListsexpectedactual的。

Is it possible to compare two ArrayLists as I've written above? 如我上面所写,可以比较两个ArrayLists吗?

The issue here is that CollectionAssert.AreEqual() will be comparing the elements using Equals() . 这里的问题是CollectionAssert.AreEqual()将使用Equals()比较元素。

For reference types that do not override Equals() , that will do a reference comparison. 对于不覆盖Equals()引用类型,将进行引用比较。 This is not what you want. 这不是您想要的。

Fortunately, you can work around this because CollectionAssert.AreEqual() has an overload that lets you specify a comparer . 幸运的是,您可以解决此问题,因为CollectionAssert.AreEqual()具有可让您指定比较器的重载

Thus, all you need to do is create a comparer which returns zero if two of the elements are equal, and non-zero if they are not. 因此,您需要做的就是创建一个比较器,如果两个元素相等,则返回零,否则返回非零。 This is slightly complicated by the fact that an ArrayList stores objects, so you need to cast to the right type to make the comparison. ArrayList存储对象这一事实使此操作有些复杂,因此您需要转换为正确的类型以进行比较。

(Note that this is somewhat of an abuse of IComparer since it is supposed to return -ve, 0 or +ve to provide an ordered comparison of the left and right hand sides. However, CollectionAssert.AreEqual() only uses it to test for equality, so it is enough for us to return zero or non-zero in our implementation. (请注意,这有点滥用IComparer因为它应该返回-ve,0或+ ve来提供左右两侧的有序比较。但是, CollectionAssert.AreEqual()仅使用它来测试相等,因此我们在实现中返回零或非零就足够了。

The AreEqual() method would ideally use an IEqualityComparer<T> to compare the elements, but I think that postdates AreEqual() so it wasn't available at the time that AreEqual() was written.) AreEqual()方法在理想情况下将使用IEqualityComparer<T>来比较元素,但我认为将AreEqual()因此在编写AreEqual()AreEqual()用。)

Assuming that your elements are of type string[] (which you say they are) then you can create a comparer to compare the elements as follows: 假设您的元素属于string[]类型(即您所说的),则可以创建一个比较器来比较元素,如下所示:

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

Then you can pass that comparer to AreEqual() . 然后,您可以将该比较器传递给AreEqual()

An example will make this clear: 一个例子可以清楚地说明这一点:

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);

This assert will succeed, but to prove that this will detect differences, change the last list2.Add() to list2.Add(Enumerable.Range(20, 9).Select(n => n.ToString()).ToArray()); 该断言将成功执行,但是要证明能够检测到差异,请将最后一个list2.Add()更改为list2.Add(Enumerable.Range(20, 9).Select(n => n.ToString()).ToArray()); and the assert will fail. 断言将失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM