2011-11-26 13 views
7

Mam dziwne zachowanie w testach, w których chcę przetestować, że wyjątek jest generowany, gdy jako parametr przekazywany jest null. Kiedy wykonać test dostaję od NUnit:Dziwne zachowanie z NUnit, ExpectedException i zwrotem plonów

System.ArgumentNullException was expected 
    -- Exception doesn't have a stack trace -- 

Moje testy:

[Test] 
[ExpectedException(typeof(ArgumentNullException))] 
public void Should_not_retrieve_any_fields_when_file_is_null() 
{ 
    _creator.CreateFields(null); 
} 

Moje wykonanie:

public IEnumerable<ImportField> CreateFields(HttpPostedFileBase file) 
{ 
    if (file == null) throw new ArgumentNullException("file"); 

    using (var reader = new StreamReader(file.InputStream)) 
    { 
     var firstLine = reader.ReadLine(); 
     var columns = firstLine.Split(new[] { ',' }); 

     for (var i = 0; i < columns.Length; i++) 
     { 
      yield return new ImportField(columns[i], i); 
     } 
    } 
} 

Czy istnieje logiczne wytłumaczenie dla tego zachowania i powinny być moje wdrażanie inaczej?

Odpowiedz

7

Przyczyna tego zachowania jest spowodowana słowem kluczowym yield. Podczas używania wydajności kompilator wygeneruje klasę dla metody z wydajnością. Podczas wywoływania tej metody kontrola jest bezwarunkowo zwracana z powrotem do osoby dzwoniącej. Nic w Twojej metodzie nie jest faktycznie wykonywane przed potrzebą.

Jeśli wyodrębnisz instrukcję używania w osobnej metodzie i zwrócisz wynik, test przejdzie pomyślnie. Lub możesz zapisać wynik do zmiennej w teście i na przykład wywołać na niej "ToList()".

public IEnumerable<ImportField> CreateFields(HttpPostedFileBase file) 
    { 
     if (file == null) throw new ArgumentNullException("file"); 

     return ExtractFromFile(file); 
    } 

    private IEnumerable<ImportField> ExtractFromFile(HttpPostedFileBase file) 
    { 
     using (var reader = new StreamReader(file.InputStream)) 
     { 
      var firstLine = reader.ReadLine(); 
      var columns = firstLine.Split(new[] { ',' }); 

      for (var i = 0; i < columns.Length; i++) 
      { 
       yield return new ImportField(columns[i], i); 
      } 
     } 
    } 
+0

+1 miły połów !! – sll