CollectionAssert与泛型一起使用?

时间:2010-03-14 04:30:40

标签: c# .net unit-testing generics mstest

似乎CollectionAssert不能与泛型一起使用。这太令人沮丧了;我想测试的代码确实使用了泛型。我是什么做的?写样板文件在两者之间转换?手动检查集合等价?

这失败了:

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

编译器错误:

错误1:

  

'System.Collections.Generic.IEnumerator&GT;'不包含'ToList'的定义,也没有扩展方法'ToList'接受类型'System.Collections.Generic.IEnumerator&gt;'的第一个参数可以找到

错误2

  

'System.Collections.Generic.IEnumerator&GT;'不包含'ToList'的定义,也没有扩展方法'ToList'接受类型'System.Collections.Generic.IEnumerator&gt;'的第一个参数可以找到

错误3

  

'System.Collections.Generic.IEnumerator&GT;'不包含'SequenceEquals'的定义,也没有扩展方法'SequenceEquals'接受类型'System.Collections.Generic.IEnumerator&gt;'的第一个参数可以找到

我做错了什么?我没有正确使用扩展程序吗?

更新:好的,这看起来好一点,但仍然不起作用:

IEnumerable<IDictionary<string, string>> expected = // ...

IEnumerable<IDictionary<string, string>> actual = // ...

CollectionAssert.AreEquivalent(expected.ToList(), actual.ToList()); // fails
CollectionAssert.IsSubsetOf(expected.ToList(), actual.ToList()); // fails

我不想比较名单;我只关心集合成员平等。成员的顺序并不重要。我怎么能绕过这个?

3 个答案:

答案 0 :(得分:35)

可以将CollectionAssert与通用集合一起使用。诀窍是要理解CollectionAssert方法在ICollection上运行,虽然很少有通用集合接口实现ICollection,但List<T>会这样做。

因此,您可以使用ToList扩展方法解决此限制:

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

那就是说,我仍然认为CollectionAssert在很多其他方面都被打破了,所以我倾向于使用Assert.IsTrue和LINQ扩展方法,如下所示:

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

FWIW,我目前正在使用这些扩展方法来执行其他比较:

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

答案 1 :(得分:5)

如果您正在使用集合,请使用此成语

HashSet<string> set1  = new HashSet<string>(){"A","B"};
HashSet<string> set2  = new HashSet<string>(){"B","A"};

Assert.IsTrue(set1.SetEquals(set2));

答案 2 :(得分:1)

您可以轻松编写自己的通用版本,然后将其移动到所有测试中使用的基类或实用程序类。基于All和Any等LINQ运算符。