C# 模拟IEnumerable的GetEnumerator()方法<;T>;类型

C# 模拟IEnumerable的GetEnumerator()方法<;T>;类型,c#,mocking,rhino-mocks,C#,Mocking,Rhino Mocks,以下测试用例在rhino模拟中失败: [TestFixture] public class EnumeratorTest { [Test] public void Should_be_able_to_use_enumerator_more_than_once() { var numbers = MockRepository.GenerateStub<INumbers>();

以下测试用例在rhino模拟中失败:

[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> { } 
[TestFixture]
公共类枚举器
{ 
[测试]
public void应该能够多次使用枚举器()
{ 
var numbers=MockRepository.GenerateStub();
numbers.Stub(x=>x.GetEnumerator()).Return(新列表
{1,2,3}.GetEnumerator());
var sut=使用senumerator()的新对象;
var correctResult=sut.dosomethingoverenumerator2次
(数字);
Assert.IsTrue(正确结果);
} 
} 
使用枚举器的公共类对象
{ 
公共布尔值为政府数字的2倍(以数字为单位)
{ 
int sum1=numbers.Sum();//返回6
int sum2=numbers.Sum();//返回0=[
返回sum1+sum2==sum1*2;
} 
} 
公共接口成员:IEnumerable{}
我认为这个测试用例有一些非常微妙的地方,我 我想这是因为我没有思考犀牛是如何嘲笑短梗的 通常,当你枚举一个IEnumerable时 从一个新的IEnumerator开始。在上面的示例中,它看起来 就像我第二次使用同一个枚举器一样 调用sum,如果枚举数已在其 序列,这将解释为什么对Sum()的第二次调用返回0。 如果是这种情况,我怎么能在这种情况下模拟GetEnumerator() 它以我希望的方式运行的方式(例如新的 枚举数或同一枚举数是否重置为位置0)

如何修改上述测试用例,使第二个.Sum()调用实际返回6而不是0?免责声明:我在Typemock工作

我不知道你是否可以使用Rhino来做这件事,但是你可以使用AAAAPI,它完全符合你的要求-

[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); 
}
[测试]
public void应该能够多次使用枚举器()
{
var numbers=Isolate.false.Instance();
当调用(()=>数字)时,将返回集合值of(新列表{1,2,3});
var sut=使用senumerator()的新对象;
var correctResult=sut.dosomethingoverenumerator2次(数字);
Assert.IsTrue(正确结果);
}
有关更多信息,请参阅《开发人员指南》。

该声明

numbers.Stub(x => x.GetEnumerator()).Return(new List<int> { 1, 2, 3 }.GetEnumerator());
numbers.Stub(x=>x.GetEnumerator()).Return(新列表{1,2,3}.GetEnumerator());
与相同

var enumerator = new List<int> { 1, 2, 3 }.GetEnumerator();
numbers.Stub(x => x.GetEnumerator()).Return(enumerator);
var枚举器=新列表{1,2,3}.GetEnumerator();
numbers.Stub(x=>x.GetEnumerator()).Return(枚举器);
在您的测试中,您告诉Rhino Mocks给相同的
IEnumerator
实例
enumerator
两次。这不是您想要的。一个
IEnumerator
实例只适合一次枚举,而不适合两次枚举(
Reset()
通常不受支持)。您希望Rhino Mock提供两个不同的
IEnumerator
实例,以便它们可以单独求和,就像调用任何其他
GetEnumerator()
函数一样。

WhenCalled()api允许您动态解析返回值

将测试用例更改为以下将允许其通过:

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

因此,与返回相同的枚举数不同,存根行为将始终返回一个新的枚举数。

是的,这就是问题所在。问题是如何模拟对单个IEnumerable对象的所有调用,以便我可以根据需要对该对象进行多次枚举。>>您如何修改上述测试用例,以使第二个.Sum()调用实际上返回的是6而不是0?谢谢!