2011-11-26 8 views
7

nullがパラメータとして渡されたときに例外がスローされることをテストするテストで奇妙な動作が発生します。私は、テストを実行すると、私はNUnitのから入手:NUnit、ExpectedException&yield yieldで奇妙な動作が発生する

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

私のテスト:

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

私の実装:

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

この動作の論理的な説明があり、私は作るべき私異なる実装ですか?

答えて

7

この現象が発生する理由は、yieldキーワードのためです。 yieldを使用すると、コンパイラーはyieldのメソッドのクラスを生成します。このメソッドを呼び出すと、コントロールは呼び出し元に無条件に戻されます。あなたのメソッドの中に、必要が生じる前に実際に実行されるものはありません。

usingステートメントを別のメソッドに抽出して結果を返すと、テストは合格になります。あるいは、結果をテスト中の変数に格納することができます。例えば、 "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すてきなキャッチ!! – sll

関連する問題