2

I wrote a Unit Test, where I want to compare two 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.

Is it possible to compare two ArrayLists as I've written above?

5
  • 1
    What do the lists contain? Without seeing any data it´s hard to guess why comparing them fails. Anyway there´s also an CollectionAssert.AreEquivalent which will check if the lists contain the same elements not considering their order. Commented Jul 31, 2017 at 12:03
  • 2
    Maybe they have the same values but they aren't the same instances. That's why your test failes I guess Commented Jul 31, 2017 at 12:03
  • @HimBromBeere The Lists are containing String Arrays Commented Jul 31, 2017 at 12:04
  • "Is it possible to compare two ArrayLists as I've written above?" Sure, exactly the way you described. However without seeing your lists it´s impossible to see why the comparison fails. Commented Jul 31, 2017 at 12:06
  • In your specific case that´s true as you´re just comparing strings. Commented Jul 31, 2017 at 12:06

1 Answer 1

5

The issue here is that CollectionAssert.AreEqual() will be comparing the elements using Equals().

For reference types that do not override Equals(), that will do a reference comparison. This is not what you want.

Fortunately, you can work around this because CollectionAssert.AreEqual() has an overload that lets you specify a comparer.

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.

(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.

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

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:

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

Then you can pass that comparer to 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()); and the assert will fail.

Sign up to request clarification or add additional context in comments.

3 Comments

If I want to write the comparer in my Program theres an Error by a).SequenceEqual that System.Array does not contain a Definition 'SequenceEqual'?
@PascalHurni SequenceEqual() is from Linq - did you put using System.Linq; at the start of your program file?
Ouu heard much about Linq but don't know what it is but this was the problem thank you! The Test Passed now will accept your anwser!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.