Rhino mocks:当存在IEnumerable <t>接口时,IEnumerator.MoveNext()问题</t>

时间:2011-03-07 18:04:41

标签: c# .net unit-testing nunit rhino-mocks

我们的API有一个继承自IEnumerable的接口:

public interface IFoos : IEnumerable<IFoo>
{
    // Additional foo-collection-specific methods
}

我正在为依赖于IFoos的课程编写单元测试。它有一个迭代IFoos的方法,如下所示:

public class Bar
{

    public IFoos Foos {get; set;}
    public void FooItUp()
    {
        foreach (IFoo foo in this.Foos)
        {
            foo.JumpAround();
        }
    }
}

在我的单元测试中,我设法将依赖关系存根并返回一个带有Rhino Mocks的枚举器,如下所示:

[Test]
public void FooItUp_JumpsUpJumpsUpAndGetsDown()
{
    // Arrange
    var mocks = new MockRepository();
    var stubFoo1 = mocks.Stub<IFoo>();
    var stubFoo2 = mocks.Stub<IFoo>();
    var stubFoos = mockRepository.Stub<IFoos>().
    var fooEnumerator = new List<IFoo> { stubFoo1, stubFoo2 }.GetEnumerator();
    stubFoos.Stub(x => x.GetEnumerator()).Return(null).WhenCalled(x => x.ReturnValue = fooEnumerator);
    Bar bar = new bar();
    bar.Foos = stubFoos;

    // Act
    bar.FooItUp();

    // Assert
    ...

}

当我尝试运行此测试时,会抛出异常:

System.InvalidOperationException : Previous method 'IEnumerator.MoveNext();' requires a return value or an exception to throw.

看看IEnumerable接口,我应该实现或设置返回值的唯一方法是GetEnumerator(),我在上面做过,对吧?为什么Bar.FooItUp()中的foreach循环只调用List枚举器上的MoveNext()?

2 个答案:

答案 0 :(得分:7)

Durrr。

在采取行动之前,我没有把我的存根放在重播状态。

添加行:

mocks.ReplayAll();

在调用bar.FooItUp()之前解决了这个问题。

答案 1 :(得分:2)

尝试更改:

stubFoos.Stub(x => x.GetEnumerator()).Return(null).WhenCalled(x => x.ReturnValue = fooEnumerator); 

要:

stubFoos.Stub(x => x.GetEnumerator()).Return(fooEnumerator);

修改:您关联的问题中的有趣信息。

看了之后,试试:

stubFoos.Stub(x => x.GetEnumerator()).Return(null).WhenCalled(x => x.ReturnValue = new List<IFoo> { stubFoo1, stubFoo2 }.GetEnumerator());