C #: Как вы тестируете метод IEnumerable.GetEnumerator ()? - PullRequest
11 голосов
/ 02 октября 2009

Допустим, у меня, например, есть этот класс, который генерирует числа Фибоначчи:

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 ]

11 голосов
/ 02 октября 2009

РЕДАКТИРОВАТЬ: Обновлено на основе того, что сказал Марк.

Ну, вы могли бы получить покрытие, выполнив:

// 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.

Я не уверен, что беспокоюсь ...

4 голосов
/ 02 октября 2009

Я бы не стал это проверять. Я бы попытался отфильтровать метод из инструмента покрытия. Я думаю, что освещение должно проверять вещи, которые я хочу охватить, и не все. Из других комментариев вы, кажется, используете TestDriven.Net. Я не знаю, насколько хорошо эти фильтры, но это было возможно с NCover. Вы также можете попробовать PartCover.

3 голосов
/ 02 октября 2009

Вы должны использовать 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());
...