Rhino 模拟:存根 IEnumerable时 IEnumerator.MoveNext() 出现问题界面

发布于 2024-10-20 11:37:00 字数 1387 浏览 2 评论 0原文

我们的 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() ?

Our API has an interface inheriting from IEnumerable like this:

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

I'm writing a unit test for a class that depends on IFoos. It has a method that iterates on an IFoos, like this:

public class Bar
{

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

In my unit test, I manage to stub out the dependency and return an Enumerator with Rhino Mocks like so:

[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
    ...

}

When I try running this test, an exception is thrown:

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

Looking at the IEnumerable interface, though, the only method I should have to implement or set a return value for is GetEnumerator() which I did above, right? Why doesn't the foreach loop in Bar.FooItUp() just call MoveNext() on the List enumerator?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

涙—继续流 2024-10-27 11:37:00

杜尔。

在对它们进行操作之前,我没有将存根置于重播状态。

在调用 bar.FooItUp() 之前添加行:

mocks.ReplayAll();

解决了该问题。

Durrr.

I wasn't putting my stubs in replay state before acting on them.

Adding the line:

mocks.ReplayAll();

before calling bar.FooItUp() fixed the issue.

暮色兮凉城 2024-10-27 11:37:00

尝试更改:

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

Try changing:

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

To:

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

Edit: interesting info in that question you linked.

Having looked at it, try:

stubFoos.Stub(x => x.GetEnumerator()).Return(null).WhenCalled(x => x.ReturnValue = new List<IFoo> { stubFoo1, stubFoo2 }.GetEnumerator()); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文