如何使用FakeItEasy伪造Enumerable类

时间:2013-12-26 14:55:24

标签: c# unit-testing ienumerable fakeiteasy

我正在学习使用/执行/编写我的代码测试并开始使用FakeItEasy作为我的假/模拟对象,现在我遇到了一个问题:

我有以下实现IEnumerable的类和实现IEnumerator的内部类(不是下面的完整代码):

public interface IEnumarableString : IEnumarable
{ }

public class AdvancedString : IEnumarableString
{
    private string[] _strings;
    private class StringEnumerator : IEnumerator
    {
            private IEnumerator GetEnumerator()
            {
                return (IEnumerator)this;
            }

            public object Current {get; set;}

            public bool MoveNext()
            {
                _position++;
                return _position < strings.Length;
            }

            public void Reset()
            {
                _position = -1;
            }
    }
    public IEnumerator GetEnumerator()
    {
           return new StringEnumerator(_strings);
    }
}

我想在我的测试中使用FakeItEasy并“假装”它的迭代行为,我尝试了以下代码,但它在需要时不会迭代自己(只是跳过foreach就像没有元素一样):

IEnumarableString stringFake = A.Fake<IEnumarableString>();

A.CallTo(() => stringFake.GetEnumerator().MoveNext()).Returns(false).Once();
A.CallTo(() => stringFake.GetEnumerator().MoveNext()).Returns(true).Once();

尝试搜索网络,但无法找到任何网络。 现在我的问题是如何配置stringFake.GetEnumerator()以返回正确的对象,以便迭代工作或我在这里做错了什么?

任何帮助都将不胜感激。

由于

2 个答案:

答案 0 :(得分:1)

如果你不能只提供具体的IEnumerable<string> @TimS建议,因为你需要额外的功能,我想我有一个解决方案。

我认为您遇到的问题是因为GetEnumerator()上未配置的stringFake将始终返回一个新的枚举器(FakeItEasy将具有未配置的属性始终返回相同的值,但未配置的方法不会缓存他们的返回值,将给新值轻松的时间)。

如果您将其配置为返回特定的枚举器,那么您应该有更好的运气。我没有编译器,但有类似的东西:

IEnumarableString stringFake = A.Fake<IEnumarableString>();
IEnumerator<string> fakeEnumerator = A.Fake<IEnumerator<string>>();

A.CallTo(() => stringFake.GetEnumerator()).Returns(fakeEnumerator);
A.CallTo(() => fakeEnumerator.MoveNext()).ReturnsNextFromSequence(true, false);

或者其他什么。请注意,您还必须在fakeEnumerator.Current上设置行为。已经有一个问题涉及伪造一个普查员。您应该能够看到它以获取更多详细信息 - Faking an enumerator in FakeItEasy

答案 1 :(得分:0)

伪装自己的对象似乎不自然,我通常只伪造我无法控制的依赖。在这种情况下,我会使用一个构造函数,让我传入一个现成的字符串数组。或者,我会使用我想要的测试行为对IEnumerableString进行不同的实现。

如果AdvancedString是被测单元,那么只需给它一些测试数据就可以了,不要试图伪造可枚举,因为这是你测试的一部分。