Using CollectionAssert with generics?

It seems that CollectionAssert cannot be used with generics. This is super disappointing; The code I want to test uses generics. What should I do? Write a template to convert between? Manually verify collection equivalence?

This fails:

 ICollection<IDictionary<string, string>> expected = // ... IEnumerable<IDictionary<string, string>> actual = // ... // error 1 and 2 here CollectionAssert.AreEqual(expected.GetEnumerator().ToList(), actual.ToList()); // error 3 here Assert.IsTrue(expected.GetEnumerator().SequenceEquals(actual)); 

Compiler Errors:

Error 1:

'System.Collections.Generic.IEnumerator>' does not contain a definition for "ToList" and does not use the extension method "ToList", which takes the first argument of the type "System.Collections.Generic.IEnumerator>", which can be found

Error 2

'System.Collections.Generic.IEnumerator>' does not contain a definition for "ToList" and does not use the extension method "ToList", which takes the first argument of the type "System.Collections.Generic.IEnumerator>", which can be found

Error 3

'System.Collections.Generic.IEnumerator>' does not contain a definition for 'SequenceEquals' and no extension method 'SequenceEquals' can be found that takes the first argument of the type 'System.Collections.Generic.IEnumerator>'

What am I doing wrong? Am I using extensions correctly?

Update: Well, this looks a little better, but still doesn't work:

 IEnumerable<IDictionary<string, string>> expected = // ... IEnumerable<IDictionary<string, string>> actual = // ... CollectionAssert.AreEquivalent(expected.ToList(), actual.ToList()); // fails CollectionAssert.IsSubsetOf(expected.ToList(), actual.ToList()); // fails 

I do not want to compare lists; I only care about membership equality. The order of members is unimportant. How can I get around this?

+32
generics c # unit-testing mstest
Mar 14 '10 at 4:30
source share
3 answers

You can use CollectionAssert with shared collections. The trick is to understand that CollectionAssert methods work on ICollection , and although some common collection interfaces implement ICollection , List<T> does.

Thus, you can get around this limitation using the ToList extension ToList :

 IEnumerable<Foo> expected = //... IEnumerable<Foo> actual = //... CollectionAssert.AreEqual(expected.ToList(), actual.ToList()); 

However, I still believe that CollectionAssert is broken in many other ways, so I prefer to use Assert.IsTrue with LINQ extension methods, for example:

 Assert.IsTrue(expected.SequenceEquals(actual)); 



FWIW, I am currently using these extension methods to perform other comparisons:

 public static class EnumerableExtension { public static bool IsEquivalentTo(this IEnumerable first, IEnumerable second) { var secondList = second.Cast<object>().ToList(); foreach (var item in first) { var index = secondList.FindIndex(item.Equals); if (index < 0) { return false; } secondList.RemoveAt(index); } return secondList.Count == 0; } public static bool IsSubsetOf(this IEnumerable first, IEnumerable second) { var secondList = second.Cast<object>().ToList(); foreach (var item in first) { var index = secondList.FindIndex(item.Equals); if (index < 0) { return false; } secondList.RemoveAt(index); } return true; } } 
+32
Mar 14
source share
β€” -

If you work with sets, use this Idiom

 HashSet<string> set1 = new HashSet<string>(){"A","B"}; HashSet<string> set2 = new HashSet<string>(){"B","A"}; Assert.IsTrue(set1.SetEquals(set2)); 
+4
May 20 '11 at 9:32 a.m.
source share

You can easily write your own generic version, and then transfer it to the base or utility class that was used in all of your tests. Configure it for LINQ statements, such as Everyone and Any.

+1
Mar 14 '10 at 4:40
source share



All Articles