2012-02-23 16 views
51

"void"を返すこの1つのメソッドの単体テストを書いています。例外がスローされないときにテストが合格するケースが1つあります。どのようにC#でそれを書くのですか?C#:ユニットテストで「例外が発生しました」をチェックするにはどうすればよいですか?

Assert.IsTrue(????) 

(私の推測では、これは私がチェックすべきかですが、「???」に何が起こっている)

私は私の質問は十分に明らかであると思います。

+0

MSTestまたはNUnitを使用していますか? –

+2

MSTestでは、キャッチされない例外が自動的にテストに失敗します。キャッチされた例外を考慮しようとしていますか? – Phil

+0

"try-catch for C#"を調べることができます。これは、スローされるスローまたはスローされないスローを処理する方法を指示します。 – Foggzie

答えて

81

例外がスローされた場合、ユニットテストは失敗します。特別なアサートを入れる必要はありません。

これは、アサーションのない単体テストが表示される数少ないシナリオの1つです。例外が発生すると、テストは暗黙的に失敗します。

あなたは本当にこのためにアサーションを書きたいしなかった場合は、 - おそらく、例外をキャッチして報告できるようにするには、「例外を期待していないが、これを得た...」、あなたがこれを行うことができます:

[Test] 
public void TestNoExceptionIsThrownByMethodUnderTest() 
{ 
    var myObject = new MyObject(); 

    try 
    { 
     myObject.MethodUnderTest(); 
    } 
    catch (Exception ex) 
    { 
     Assert.Fail("Expected no exception, but got: " + ex.Message); 
    } 
} 

(上記はNUnitの例ですが、MSTestでも同様です)

+0

明らかに、この例外が成り立つためには行かないでください。 – Servy

+5

キャッチされない例外がスローされた場合にのみ、テストは失敗します。例外ハンドラ内のコードに依存して、単体テストが合格することがあります。 – ediblecode

9

doesn't happenをテストしないでください。コードを壊さないことは保証のようです。これは暗黙のことですが、私たちはすべて、バグのないノン・ブレーク・コードを目指しています。あなたはそのためのテストを書いてみたいですか?なぜただ一つの方法? いくつかの例外をスローしないように、あなたのすべてのメソッドがテストされていますか??その道に続いて、に、コードベース内のすべてのメソッドに対して1つの余分なダミーのアサートレステストが完成します。それは価値がない。

もちろん

あなたの条件がキャッチ例外を行う方法を検証することであるならば、あなたはそれをテストします(またはそれを少し逆転、それはキャッチすることになっているものを投げていないことをテスト)。

しかし、一般的なアプローチ/プラクティスはそのままです。テストされたコードの範囲外の人為的/曖昧な要件のテストを書くことはありません(「動作する」または「投げない」というテストは通常はそのような例 - 特に、メソッドの責任がよく分かっているシナリオ)。

あなたのコードの内容に簡単に焦点を当てて、とそれをテストします。

+4

-1私は、必要な正の機能と例外をスローしないと考えることができます。 1つの方法では、例外を処理し、その例外を投げることなくログに記録し、アクションを実行することです。あなたは良い一般的な点を作っていますが、常に真実であるかのように_絶対的に話してください。 –

+0

@RobLevine:ロギング中にあなたのサンプルがスローされるとどうなりますか?あなたはそれがないと主張し、それについてのテストを持っていますか?それが私の全ポイントでした。私は「宗教的」とは言いませんでしたが(downvoteの理由を理解することもありません)、何かが起こらないと主張しています*、一般的には非常に逆効果です。あなたは通常、反対にしたい、あなたのコードをアサートする*何かをする*。それは簡単に簡単です。 –

+0

私はあなたのことを理解しています - それは良い_general_アドバイスです。問題は、あなたが絶対的なものから始める瞬間、あなたはコアポイントにダメージを与えます。テスト中のコードの性質が例外をスローさせようとするのであれば、例外がスローされないことを保証するために_positive_アサーションです。あなたの全体的なポイントは良いものですが、一般的なケースでは_ですが、それはあなたがそれをフレーム化した方法だったと思います。 -1はちょっとひどかった - 私は数分後に自分の気分を変えましたが、あなたの投稿を編集しない限り+1できません。申し訳ありません。 –

16

NUnitのでは、あなたが使用することができます。

Assert.DoesNotThrow(<expression>); 

はあなたのコードが例外をスローしないことを主張します。その周囲にAssertがなくても例外がスローされてもテストは失敗しますが、このアプローチの利点は、テストで満たされていない期待とバグを区別できることです。テスト出力に表示されます。うまく言葉を出したテスト出力は、テストで失敗したコードのエラーを特定するのに役立ちます。

あなたのコードが例外をスローしないようにテストを追加することは有効です。たとえば、入力を検証していて、入ってくる文字列をlong型に変換する必要があるとします。文字列がnullであり、これが受け入れられる場合があるため、文字列変換が例外をスローしないようにする必要があります。したがって、この機会に対処するコードがあります。もしあなたがそれについてのテストを書いていなければ、あなたは重要なロジックの周りにカバレッジを失います。

+1

明示的なDoesNotThrowは素晴らしいです。 Assert。*をテストで見たことに慣れているなら、他の人が怠け者で、忘れていたと思うかもしれません。 –

+0

vstestまたはmstestにそれに相当するものはありますか? –

+1

@DanCsharpster、少なくともMSTestにはないと思います - これまでMSTestでこの機能を必要としていたとき、私はこのようなことをしました: 'public class TestBase { // believe私は、あなたがしているよりもこれ以上好きではありません。 protected void AssertDoesNotThrow(アクションアクション、文字列メッセージ) { try { action(); (例外) { } } } } ' – Clarkeye

3

このヘルパークラスはMSTestで私のかゆみを傷つけました。たぶんそれもあなたを傷つけることができます。

[TestMethod] 
public void ScheduleItsIneligibilityJob_HasValid_CronSchedule() 
{ 
    // Arrange 
    var factory = new StdSchedulerFactory(); 
    IScheduler scheduler = factory.GetScheduler(); 

    // Assert 
    AssertEx.NoExceptionThrown<FormatException>(() => 
     // Act 
     _service.ScheduleJob(scheduler) 
    ); 
} 

public sealed class AssertEx 
{ 
    public static void NoExceptionThrown<T>(Action a) where T:Exception 
    { 
     try 
     { 
      a(); 
     } 
     catch (T) 
     { 
      Assert.Fail("Expected no {0} to be thrown", typeof(T).Name); 
     } 
    } 
} 
1

私は一貫性のために、各テストの終わりにAssert.Whateverを見たい...は、一つせずに、私は本当にそこに一つであることがわからそこになっていないことができますか?

私にとっては、これは私が誤ってがそこにそのコードを配置し、従って私はそれを通じて迅速なスキムミルクで十分な自信を持ってする必要があります。このだっないなかったを知っAssert.IsTrue(true);

を置くのと同じくらい簡単です思惑通り。

[TestMethod] 
    public void ProjectRejectsGappedVersioningByDefault() { 

     var files = new List<ScriptFile>(); 
     files.Add(ScriptProjectTestMocks.GetVersion1to2()); 
     files.Add(ScriptProjectTestMocks.GetVersion3to4()); 

     Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => { 
      var sut = new ScriptProject(files); 
     }); 

    } 

    [TestMethod] 
    public void ProjectAcceptsGappedVersionsExplicitly() { 

     var files = new List<ScriptFile>(); 
     files.Add(ScriptProjectTestMocks.GetVersion1to2()); 
     files.Add(ScriptProjectTestMocks.GetVersion3to4()); 

     var sut = new ScriptProject(files, true); 

     Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like 

    } 
関連する問題