如何模拟IEnumerable <t>以便我可以测试接收它的方法</t>

时间:2009-11-13 12:03:24

标签: .net unit-testing mocking moq

我有一个我想测试的方法,它希望IEnumerable<T>作为参数。

我目前正在嘲笑IEnumerable<T>的内容如下(使用Moq):

 var mockParent = new Mock<ICsvTreeGridExportable>();
 var mockChild = new Mock<ICsvTreeGridExportable>();

如何将这些模拟对象放在IEnumerable<T>中,以便我可以将它们作为参数传递给我想要测试的方法?

我正在测试的方法希望收到IEnumerable<ICsvTreeGridExportable>

5 个答案:

答案 0 :(得分:20)

我只想使用集合intialiser语法创建一个数组。即。

var mockParent = new Mock<ICsvTreeGridExportable>();
var mockChild = new Mock<ICsvTreeGridExportable>();

TestMethod(new[] { mockParent.Object, mockChild.Object });

.NET中的数组实现了IEnumerable<T>接口,所以你们都已经设置好了。

注意:如果你想要一个“纯粹的”IEnumerable<T>(正如Luke指出的那样),你可以使用一点LINQ来做到这一点:

TestMethod((new[] { mockParent.Object, mockChild.Object }).TakeWhile(true));

答案 1 :(得分:6)

你可以创建一个数组。 (数组实现IEnumerable<T>接口。)

var mockEnumerable = new[] { mockParent.Object, mockChild.Object };

如果你想要一个无法强制转换为数组等的“纯”IEnumerable<T>,那么你可以使用辅助方法创建它:

var mockEnumerable = CreateEnumerable(mockParent.Object, mockChild.Object);

// ...

public static IEnumerable<T> CreateEnumerable<T>(params T[] items)
{
    foreach (T item in items)
    {
        yield return item;
    }
}

(正如Jamie在评论中提到的,您需要使用模拟的对象,而不是 Mock 对象。例如,mockParent.ObjectmockChild.Object等,只是mockParentmockChild。)

答案 2 :(得分:1)

你可以做这样的事情:
创建一个函数Dummy

private IEnumerable<ICsvTreeGridExportable> Dummy()
{
     yield return new ICsvTreeGridExportable();
}

在你的测试功能中执行类似

的操作
private void TestFunction()
{
   ThisIsTheOneThatNeedsIenumerable(Dummy());
}

希望有所帮助

答案 3 :(得分:0)

List<ICsvTreeGridExportable> myList = new List<ICsvTreeGridExportable>();
myList.Add(mockParent);
myList.Add(mockChild);
return myList;

答案 4 :(得分:0)

以下是塞巴斯蒂安答案的替代方案,可让您指定任何类型的假人:

private IEnumerable<T> GetDummies<T>(int numDummies) where T : new() {
    for (int i = 0; i < numDummies; i++) yield return new T();
    yield break;
}

或者(如果你想使用能够使用没有空构造函数的类型):

private IEnumerable<T> GetDummies<T>(Func<T> generator, int numDummies) {
    for (int i = 0; i < numDummies; i++) yield return generator.Invoke();
    yield break;
}