Носороги носорога: проблема с IEnumerator.MoveNext () при заглушении интерфейса IEnumerable <T> - PullRequest
6 голосов
/ 07 марта 2011

Наш 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();
        }
    }
}

В моем модульном тесте мне удается заглушить зависимость и вернуть Enumerator с 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 (), который я сделал выше, верно? Почему цикл foreach в Bar.FooItUp () просто не вызывает MoveNext () в перечислителе списка?

Ответы [ 2 ]

7 голосов
/ 08 марта 2011

Durrr.

Я не переводил свои заглушки в состояние воспроизведения, прежде чем действовать на них.

Добавление строки:

mocks.ReplayAll();

перед вызовом bar.FooItUp() исправил проблему.

2 голосов
/ 07 марта 2011

Попробуйте изменить:

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