0

In my company code base we have a bunch of extension method for IEnumerable object.

Some of this method enumerate multiple time the parameter given in entry.

Of course, we don't want the so I'm going to fix those methods.

But first I would like to write some unit test to detect the multiple enumeration.

I come to an implementation of IEnumerable that provide enumeration count information :

public class TestableEnumerable<T> : IEnumerable<T>
{
    readonly T[] values;

    public TestableEnumerable(T[] values)
    {
        this.values = values;
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

    public IEnumerator<T> GetEnumerator()
    {
        EnumerationCount++;
        foreach (var value in values)
        {
            yield return value;
        }
    }

    public int EnumerationCount { get; private set; }
}

The test look like this:

[TestFixture]
public class EnumerableExtensionsTests
{
    TestableEnumerable<int> sut;

    [SetUp]
    public void SetUp()
    {
        sut = new TestableEnumerable<int>(new[] { -10, 0, 10 });
    }

    [Test]
    public void Append_Enumerate_Once()
    {
        var result = sut.Append(1).ToArray();
        Assert.That(sut.EnumerationCount, Is.EqualTo(1));
    }
}

Does NUnit provide any mechanism to accomplish this more lightly ?

klashar
  • 2,519
  • 2
  • 28
  • 38
Orace
  • 7,822
  • 30
  • 45

1 Answers1

1

If you looks only for GetEnumerator method calls count, you can use any mock framework to create fake enumerable. There is NUnit.Mock framework. But now it's no longer being developed and NUnit project uses NSubstitute.

var fakeEnumerable = Substitute.For<IEnumerable<int>>();
fakeEnumerable.GetEnumerator().Returns(Substitute.For<IEnumerator<int>>());

fakeEnumerable.ToArray();
fakeEnumerable.ToArray();

fakeEnumerable.Received(2).GetEnumerator();

Also there is another way to enumerate collection twice. It can be done by using IEnumerator.Reset metod. So it may worth to check Reset method calls too.

Kote
  • 2,116
  • 1
  • 19
  • 20