NUnit 是否提供多重枚举助手?

Does NUnit provide a multiple enumeration helper?

在我公司的代码库中,我们有一堆 IEnumerable 对象的扩展方法。

此方法中的某些方法会多次枚举条目中给定的参数。

当然,我们不需要,所以我将修复这些方法。

但首先我想写一些单元测试来检测多重枚举。

我来实现 IEnumerable 提供枚举计数信息:

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; }
}

测试看起来像这样:

[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));
    }
}

NUnit 是否提供任何机制来更轻松地完成此任务?

如果您只查找 GetEnumerator 方法调用计数,则可以使用任何模拟框架来创建伪造的可枚举。 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();

还有一种方法是枚举集合两次。它可以通过使用 IEnumerator.Reset 方法来完成。 因此也值得检查 Reset 方法调用。