Mocking GetEnumerator() method of an IEnumerable<T> types

故事扮演 提交于 2019-12-03 05:53:46
programmer

The WhenCalled() api lets you dynamically resolve return values.

Changing the test case to the following will allow it to pass:

numbers.Stub(x => x.GetEnumerator())
                     .Return(null)
                     .WhenCalled(x => x.ReturnValue = 
                                    new List<int> { 1, 2, 3 }.GetEnumerator()
                                 );

So instead of returning the same enumerator, the stubbed behavior will always return a new enumerator.

The statement

numbers.Stub(x => x.GetEnumerator()).Return(new List<int> { 1, 2, 3 }.GetEnumerator());

is identical to

var enumerator = new List<int> { 1, 2, 3 }.GetEnumerator();
numbers.Stub(x => x.GetEnumerator()).Return(enumerator);

In your test, you are telling Rhino Mocks to give the identical IEnumerator<int> instance enumerator twice. That's not what you intended. A single instance of IEnumerator<int> is good only for one enumeration, not two enumerations (Reset() is not supported, typically). You intended Rhino Mocks to give two different instances of IEnumerator<int>, so that they can be summed separately, just as any call to any other GetEnumerator<int>() function would do.

Disclaimer: I work at Typemock

I don't know if you can use Rhino to do this but you can use Isolator with AAA API that has exactly what you're looking for -

[Test] 
public void Should_be_able_to_use_enumerator_more_than_once() 
{
   var numbers = Isolate.Fake.Instance<INumbers>();
   Isolate.WhenCalled(() => numbers).WillReturnCollectionValuesOf(new List<int>{ 1, 2, 3 });
   var sut = new ObjectThatUsesEnumerator(); 
   var correctResult = sut.DoSomethingOverEnumerator2Times(numbers); 
   Assert.IsTrue(correctResult); 
}

For more info see Managing Collections in the Developer Guide.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!