如何使用 Rhino 模拟来模拟 IEnumerable.First() 方法

本文关键字:模拟 方法 First 何使用 Rhino IEnumerable | 更新日期: 2023-09-27 18:32:37

我有一个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>抛出了上述异常。我该如何解决?我也尝试通过模拟GetEnumerator()方法调用来返回IEnumerator。这也无济于事。

如何使用 Rhino 模拟来模拟 IEnumerable.First<T>() 方法

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

不能存根对First<T>()的调用,因为它是静态扩展方法。它不是在IEnumerable<T>中定义的,它是Enumerable的成员。

因此,您需要在IEnumerable<T>存根上存根GetEnumerator()以返回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>()
};

存根/模拟集合接口类型是一个非常糟糕的主意 - 一定要使用该接口,但在测试中使用实际集合将其备份。