2011-11-26 11 views
7

Ho un comportamento strano in un test in cui voglio verificare che venga generata un'eccezione quando viene passato come parametro un valore nullo. Quando eseguo il test che ricevo da NUnit:Strano comportamento con NUnit, ExpectedException e rendimento restituito

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

La mia prova:

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

mia realizzazione:

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

C'è una spiegazione logica a questo comportamento e dovrei fare il mio implementazione diversa?

risposta

7

Il motivo per cui si sta verificando questo comportamento è dovuto alla parola chiave yield. Quando si utilizza yield, il compilatore genererà una classe per il metodo con la resa in esso. Quando si chiama quel metodo, il controllo viene restituito incondizionatamente al chiamante. Nulla nel tuo metodo viene effettivamente eseguito prima che sia necessario.

Se si estrae l'istruzione using in un metodo separato e si restituisce il risultato, il test verrà superato. Oppure è possibile memorizzare il risultato in una variabile del test e ad esempio richiamare "ToList()" su di esso.

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 bella cattura !! – sll