我如何使用Rhino模拟模拟IEnumerable.First <t>()方法?</t>

时间:2013-09-25 04:53:24

标签: c# rhino-mocks

我有一个IEnumerable<T>集合,我想模拟First<T>()方法调用。 当我尝试这样做时,我得到了这个:

  

上一个方法'IEnumerator.MoveNext();'需要返回值或抛出异常。

我正在粘贴以下代码:

IEnumerable<T> collection = MockRepository
    .GenerateStub<IEnumerable<T>>();
collection
    .Stub(x => x.First<T>())
    .IgnoreArguments()
    .Return(MockRepository.GenerateStub<T>());

但是x.First<T>抛出了上述异常。我该如何解决?我尝试通过模拟IEnumerator方法调用来返回GetEnumerator()。它也没有帮助。

1 个答案:

答案 0 :(得分:5)

我将假设T存在,因为代码在通用函数中。

您无法将调用存根到First<T>(),因为它是一种静态扩展方法。它未在IEnumerable<T>中定义,它是Enumerable的成员。

因此,您需要在GetEnumerator()存根上存根IEnumerable<T>以返回IEnumerator<T>存根,该存根返回所需类型的存根:

IEnumerator<T> enumerator = MockRepository.GenerateStub<IEnumerator<T>>();
enumerator.Stub(x => x.MoveNext()).Return(true);
enumerator.Stub(x => x.Current).Return(MockRepository.GenerateStub<T>());
enumerator.Stub(x => x.MoveNext()).Return(false);

IEnumerable<T> collection = MockRepository.GenerateStub<IEnumerable<T>>();
collection.Stub(x => x.GetEnumerator()).Return(enumerator);

但是,我强烈建议不要试图模仿IEnumerable。使用带有单个项目的List<>可以更容易地进行初始编码并稍后阅读,而且不那么脆弱:

List<T> listOfT = new List<T>
{
    MockRepository.GenerateStub<T>()
};

存根/模拟集合接口类型是一个非常糟糕的主意 - 通过各种方式使用接口,但在测试中将其与实际集合一起使用。