C#:你如何测试IEnumerable.GetEnumerator()方法?

时间:2009-10-02 14:54:27

标签: c# unit-testing ienumerable

假设我举例说这个类生成斐波纳契数:

public class FibonacciSequence : IEnumerable<ulong>
{
    public IEnumerator<ulong> GetEnumerator()
    {
        var a = 0UL;
        var b = 1UL;
        var c = a + b;
        while (true)
        {
            yield return c;
            c = a + b;
            a = b;
            b = c;
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

然后我可以编写一个测试,确保序列中的n个第一个数字是正确的。

    [Test]
    public void GetEnumerator_FirstFifteenNumbers_AreCorrect()
    {
        var sequence = new FibonacciSequence().Take(15).ToArray();
        CollectionAssert.AreEqual(sequence, new[] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610});
    }

当我检查覆盖范围时,我会看到IEnumerable.GetEnumerator()方法未经测试,我的覆盖率将低于实际需要的范围。很公平。但是我该如何测试这种方法呢?

你通常如何处理这个?

3 个答案:

答案 0 :(得分:11)

编辑:根据Marc所说的更新。

嗯,你可以通过以下方式获得报道:

// Helper extension method
public static IEnumerable AsWeakEnumerable(this IEnumerable source)
{
    foreach (object o in source)
    {
        yield return o;
    }
}

...

[Test]
public void GetEnumerator_FirstFifteenNumbers_AreCorrect()
{
    IEnumerable weak = new FibonacciSequence().AsWeakEnumerable();
    var sequence = weak.Cast<int>().Take(15).ToArray();
    CollectionAssert.AreEqual(sequence, 
        new[] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610});
}

请注意,weak被声明为非通用IEnumerable类型...这意味着您需要在其上调用Cast以将每个返回的对象强制转换为int

我不确定我是否会打扰......

答案 1 :(得分:4)

我不会测试它。我会尝试从coverage工具中过滤掉该方法。我认为报道应该检查我想要涵盖的内容而不是所有内容。从其他评论您似乎使用TestDriven.Net。我不知道过滤器有多好,但NCover可能。你也可以试试PartCover。

答案 2 :(得分:3)

您必须使用use IEnumerable(非泛型);我使用Cast<T>发布了一个回复,但这仍然会作弊(它检查了所需的类型作为特例) - 您可能需要以下内容:

public static int CountUntyped(this IEnumerable source) {
    int count = 0;
    foreach(object obj in source) { count++; }
    return count;
}

IEnumerable<T> source = ...
Assert.AreEqual(typed.Count(), source.CountUntyped());