2009-10-02 14 views
10

Powiedzmy, że na przykład mieć tej klasy, który generuje liczb Fibonacciego:C#: Jak testujesz metodę IEnumerable.GetEnumerator()?

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

mogę następnie napisać test, który zapewnia, że ​​n pierwszych liczb w kolejności są poprawne.

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

Kiedy sprawdzić zasięg będzie jednak widzę, że metoda IEnumerable.GetEnumerator() jest niesprawdzone, a mój zasięg będzie mniejszy niż to naprawdę musi być. Słusznie. Ale jak mam przetestować tę metodę?

Jak zwykle sobie z tym radzisz?

+0

hmm, z ciekawości, w jaki sposób sprawdzasz zasięg testu? Brzmi jak interesująca funkcja. – Ian

+1

Tak, też się nad tym zastanawiałem, hehe. Ale znalazłem przycisk do niego w TestDriven.Net, który jest całkiem niesamowity przy okazji. Jeśli nie spróbowałeś, powinieneś! Po zainstalowaniu możesz kliknąć prawym przyciskiem myszy na swoje rozwiązanie (w eksploratorze rozwiązań) i wybrać opcję Testuj z -> Zasięg. To proste :) – Svish

+0

Jeśli masz wersję VS Team System, narzędzia testowe zawierają również narzędzie do pokrycia, które możesz wywołać za pomocą TestDriven.Net lub w zwykłym interfejsie. W przeciwnym razie, jeśli korzystasz z google testowych narzędzi pokrycia dla Visual Studio, jest ich kilka. Program NCover może być najczęściej używany. – McMuttons

Odpowiedz

11

EDIT: Aktualizacja na podstawie tego, co powiedział Marc.

Dobrze mógł uzyskać zasięg w górę wykonując:

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

Zauważ, że weak jest uznany za nongeneric IEnumerable typ ... co oznacza, że ​​trzeba zadzwonić Cast na to rzucić każdy zwrócony obiekt do int.

Nie jestem pewna, że ​​przeszkadza chociaż ...

+1

Nie - sprawdziłem, i 'Cast ' faktycznie sprawdza przez 'jako' dla 'IEnumerable ', więc skończysz używając 'IEnumerable .GetEnumerator()', a nie 'IEnumerable.GetEnumerator()' –

+0

To też zobaczyłem. Więc nie byłem do końca pewien, jak to zrobić, hehe. – Svish

+0

Naprawiono, dzięki chłopaki - to sprawa zawijania silnej wersji w słabych ... –

3

Będziesz musiał użyć użyć IEnumerable (nietypowy); Zamieściłem odpowiedź korzystając Cast<T>, ale to nadal będzie oszukiwać (to sprawdzone żądanego typu jako szczególny przypadek) - może trzeba coś jak:

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()); 
+1

Ale to wystarczy porównać liczbę przedmiotów w wyliczeniach, prawda? A w moim przypadku to by się źle zaczęło, ponieważ FibonacciSequence nigdy tak naprawdę się nie kończy: p – Svish

+0

Lol! Tak, rozumiem. Ale tym, co próbuję podkreślić, jest praca z 'IEnumerable' zamiast' IEnumerable '- i nie sądzę, żebyś mógł po prostu użyć' Cast ', 'bo wygląda ... –

4

nie będę go przetestować. Próbowałbym odfiltrować tę metodę z narzędzia pokrycia. Myślę, że zasięg powinien sprawdzać rzeczy, które chcę mieć, a nie wszystko. Z innych komentarzy wynika, że ​​korzystasz z TestDriven.Net. Nie wiem, jak dobrze to filtruje, ale było to możliwe z NCover. Możesz też wypróbować PartCover.

+0

Oczywiście, i nie biję się nad tym lub cokolwiek. Po prostu ciekawi, jak sobie z tym poradzą inni :) – Svish

+0

@Svish - przepraszam, odpowiedź brzmi bardziej wyczerpująco, niż zamierzałem. Ale naprawdę bym się zajął filtrowaniem rzeczy. Myślę, że to lepsze niż próba dodania do niego testu. –

Powiązane problemy