В носорогах из носорога возникает следующий тестовый случай:
[TestFixture]
public class EnumeratorTest
{
[Test]
public void Should_be_able_to_use_enumerator_more_than_once()
{
var numbers = MockRepository.GenerateStub<INumbers>();
numbers.Stub(x => x.GetEnumerator()).Return(new List<int>
{ 1, 2, 3 }.GetEnumerator());
var sut = new ObjectThatUsesEnumerator();
var correctResult = sut.DoSomethingOverEnumerator2Times
(numbers);
Assert.IsTrue(correctResult);
}
}
public class ObjectThatUsesEnumerator
{
public bool DoSomethingOverEnumerator2Times(INumbers numbers)
{
int sum1 = numbers.Sum(); // returns 6
int sum2 = numbers.Sum(); // returns 0 =[
return sum1 + sum2 == sum1 * 2;
}
}
public interface INumbers : IEnumerable<int> { }
Я думаю, что в этом тестовом случае есть что-то очень тонкое, и я думаю, что это от меня, не думая, как Rhino Mocks stubbing фактически работает. Как правило, когда вы перечислите IEnumerable, вы начинаются со свежего IEnumerator. В приведенном выше примере он выглядит как я мог бы повторно использовать тот же счетчик во второй раз, когда я вызывающая сумма, и если счетчик уже находится в конце последовательность, которая объясняет, почему второй вызов Sum() возвращает 0. Если это так, то как я мог высмеивать GetEnumerator() в таких способ, которым он ведет себя так, как я этого хочу (например, новый перечислитель или тот же счетчик reset в позицию 0)?
Как бы вы изменили вышеуказанный тестовый пример, так что второй вызов .Sum() фактически возвращает 6 вместо 0?