Sravan Kumar
Sravan Kumar

Reputation: 1457

CollectionAssert.AreEquivalent vs Assert.Equals()

public void NumericListCanBeSorted()
{
  var sorted = sort.SortNumbers(nums);
  Assert.AreEqual(sorted, nums);
}

public List<int> SortNumbers(List<int> nums)
    {
        List<int> sortedList = new List<int>();

        for (int i = 0; i < nums.Count(); i++)
        {
            for (int j = i + 1; j < nums.Count; j++)
            {
                if (nums[i] > nums[j])
                {
                    //Swapping values
                    nums[i] = nums[i] + nums[j];
                    nums[j] = nums[i] - nums[j];
                    nums[i] = nums[i] - nums[j];
                }
            }
            sortedList.Add(nums[i]);
        }
        return sortedList;
    }

Result Message: Assert.AreEqual failed. 
Expected:     <System.Collections.Generic.List`1[System.Int32]>. 
      Actual :<System.Collections.Generic.List`1[System.Int32]>.

The datatypes of expected and actual are same. Still test failed. Cannot understand why? Can someone please help me know the reason.Moreover, it works for the following function.

  public List<int> SortNumbers(List<int> nums)
    {
        List<int> sortedList = new List<int>();
        for (int i = 0; i < nums.Count(); i++)
        {
            for (int j = i + 1; j < nums.Count; j++)
            {
                if (nums[i] > nums[j])
                {
                    //Swapping values
                    nums[i] = nums[i] + nums[j];
                    nums[j] = nums[i] - nums[j];
                    nums[i] = nums[i] - nums[j];
                }
            }
        }
        sortedList = nums;
        return sortedList;
    }

Upvotes: 11

Views: 14633

Answers (1)

Der Kommissar
Der Kommissar

Reputation: 5953

Reference type comparisons.

Try using CollectionAssert.AreEqual or CollectionAssert.AreEquivalent.

https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.collectionassert.areequivalent.aspx

Here's what happens:

You use Assert.AreEqual(List<int>, List<int>), of which, the CLR/.NET goes in and says, "is the reference of List 1 the same as List 2?" The result is no, therefore, the CLR/.NET returns false.

CollectionAssert enumerates the arrays (which is what Lists are internally) and determines if they have the same items. CollectionAssert.AreEqual checks that they have the same items in the same order. CollectionAssert.AreEquivalent checks that they have the same items, in any order.

ANY array/List/Dictionary MUST use CollectionAssert for such comparisons.

For example:

List<int> l1 = new List<int>();
List<int> l2 = l1;
Assert.AreEqual(l1, l2);

This will result in true, due to l2 having been set to the same reference as l1.

However:

List<int> l1 = new List<int>();
List<int> l2 = new List<int>();
Assert.AreEqual(l1, l2);

This will result in a false due to l2 having been made a NEW reference to a NEW object. Whereas:

CollectionAssert.AreEqual(l1, l2);

This will result in a true in either situation above. This is because the CLR/.NET actually goes through the list and inventories it, essentially.

Another edit, because I wanted to clarify further; you can also use CollectionAssert.AreEquivalent, which will not guarantee the items in the same order, but will simply guarantee that the arrays/Lists/Dictionaries have the same quantities of the same items. I.e.:

1,2,3,3,2,1
1,3,2,2,3,1

This will result in true with CollectionAssert.AreEquivalent, but false with CollectionAssert.AreEqual.

Upvotes: 37

Related Questions