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