2012-03-27 8 views
12

私はファイルを作成するクラスを持っています。NUnitを使用して任意のタイプの例外をテストする

私は現在、クラスが正常であることを確認するための統合テストを行っています。

無効なディレクトリとファイル名を渡して、例外がスローされるようにしています。私のテストで

は、私が使用しています:ArgumentExceptionががスローされるよう

[Test] 
public void CreateFile_InvalidFileName_ThrowsException() 
{ 
    //Arrange 
    var logger = SetupLogger("?\\"); 

    //Act 

    //Assert 
    Assert.Throws<Exception>(()=> logger.CreateFile()); 
} 

ただし、このシナリオでテストが失敗しています。私はそれが合格するだけの例外を追加することによって考えました。

このパスにExceptionを使用する方法はありますか?

+1

特定の例外をテストするために良いでしょう一つの理由は、ロガーのクライアントは、おそらくベース 'Exception'クラスをキャッチすることを避けるためにしたいということであり、したがって、特定の例外に依存していますスローされるので、それはあなたがテストすべきものです。 – Ergwun

答えて

21

Assert.Throws<>のヘルプは、それがどんなExceptionをキャッチするよう

Assert.Thatバージョンを試してみてください「と呼ばれるとき、デリゲートは例外の特定のタイプをスロー検証」と述べていますそれを検証のために使用してください。

NUnitの2.5
/// <summary> 
    /// Throwses the specified action. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="action">The action.</param> 
    /// <returns></returns> 
    public static T Throws<T>(Action action) where T : Exception 
    { 
     try 
     { 
      action(); 
     } 
     catch (T ex) 
     { 
      return ex; 
     } 

     Assert.Fail("Expected exception of type {0}.", typeof(T)); 
     return null; 
    } 
+0

+1これは実際に質問に答えますが、特定の例外をテストするための他の回答の良いアドバイスは無視しないでください。 – Ergwun

+0

例外のプロパティをチェックするか、後で入力する必要がある場合は、 'var ex = Assert.Throws(Is.AssignableTo(typeof(Exception))、()=> DoSomething()); ' –

1

属性ExpectedExceptionを使用してテストメソッドにタグを付けることができます。それはうまくいくはずです。

[ExpectedException(typeof(Exception))] 
    public void TestException() 
    { 

    } 
+0

Roy Osheroveの本を読んだ後、私はその属性を使用しないようにしています – Jon

+0

興味深いことに、私は実用的な単体テストを読んでおり、属性を使うことを奨励しています。なぜそれらを使用しないように精巧に注意しますか?私はリンクやブログについて嬉しいです。 – Alex

+0

私は本の中でそれを見つけることができませんので、おそらく彼のTDDコースでした。http://tekpub.com/productions/tdd – Jon

2

あなたの例外は、決定論的であるべきであり、あなたは、特定の例外がスローされます、そしてあなたがその特定の例外をテストする条件を設定し、テストケースを記述することができるはずです。このように、あなたのテストは

CreateFile_InvalidFileName_ThrowsArgumentException 

Assert.Throws<ArgumentException>(() => logger.CreateFile()); 

編集のように書き換えるべきである

:ところで

は、私はあなたのコンストラクタは無効なファイル名を検出し、そこに投げれるべきだと思います。そして、ファイル名が有効であることをコンストラクタのための契約にする必要があります。

+0

私は同意します。しかし、ファイルを作成するときには、考えなければならない多くの例外があり、多くの例外がスローされる可能性があります。この種のシナリオで既に事前に書かれた統合テストがあるのだろうかと疑問に思う。 – Jon

+0

+1質問に答えなくても、私はこのアドバイスに同意する。あなたのクラスがスローする例外の型は、それのパブリックAPIの一部を形成するので、テストする必要があります。 – Ergwun

+0

@Jonは、BCLの特定のメソッドによって投げられる可能性のあるさまざまなタイプの例外の数に悩まされることに同意しました。あなたのロガークラスが友好的であることを望むならば、それはそれらの例外をキャッチして、元の内部例外として1つの例外(または少なくとも少数の例外)をラップすることができます。その後、自動テストでその例外を明示的にテストする必要があります。 – Ergwun

1

通常、特定の例外をテストして、コードがさまざまなエラーに対して適切に応答していることを確認してください。

がテストのために例外であることを実際に許可する必要がある場合は、標準的なtry/catchブロックと通常のSuccess/Failureアサートを使用してください。

private class Thrower 
{ 
    public void ThrowAE() { throw new ArgumentException(); } 
} 

[Test] 
public void ThrowETest() 
{ 
    var t = new Thrower(); 
    Assert.That(() => t.ThrowAE(), Throws.Exception); 
} 
1

独自のメソッドを書く:

4

// Allow both ApplicationException and any derived type 
Assert.Catch<ApplicationException>(() => logger.CreateFile()); 

// Allow any kind of exception 
Assert.Catch(() => logger.CreateFile()); 
+0

' Assert.Catch ' 'Assert.Throw 'のように、ドットに対して*と*の質問を解決すると、例外として結果を得ることができます: 'var ex = Assert.Catch (()=> ..); AssertMoreOnException(ex); '。 – user2864740

0

Throws.InstanceOf(上記)は、代わりに、より具体的な派生型で、ベース・例外の種類を通過することを可能にします。

[Test] 
public void CreateFile_InvalidFileName_ThrowsException() 
{ 
    //Arrange 
    var logger = SetupLogger("?\\"); 

    //Act 

    //Assert 
    Assert.That(() => logger.CreateFile(), Throws.InstanceOf<Exception>()); 
} 
関連する問題