2013-07-23 6 views
17

Nunitのテストプログラムで、メッセージの検証によって書き込み例外例外が発生していることを確認したいと思います。NunitでのArgumentExceptionとそのメッセージの確認C#

[Test] 
    public void ArgumentsWorkbookNameException() 
    { 
     const string workbookName = "Tester.xls"; 
     var args = new[] { workbookName, "Sheet1", "Source3.csv", "Sheet2", "Source4.csv" }; 
     Assert.Throws(typeof(ArgumentException), delegate { var appargs = new ApplicationArguments(args); }, "Invalid ending parameter of the workbook. Please use .xlsx"); 

    } 

これをテストした後、メインプログラムでメッセージを修正したときにこれが機能しなくなりました。

 int wbLength = args[0].Length; 

     // Telling the user to type in the correct workbook name file. 
     if (args[0].Substring(wbLength-5,5)!=".xlsx") 
     { 
      throw new ArgumentException(
       "Invalid ending parameter of the workbook. Please use .xlsx random random"); 
     } 

メッセージを変更したかどうかにかかわらず、単体テストは引き続き通過しました。

どうすればよいですか?または、C#にそのようなことはありません。私の同僚は、RubyやRSPECのようなオプションがあると言いましたが、C#では100%確実ではありません。

答えて

3

Assert.Throwsのメッセージパラメータは予期される例外メッセージではありません。テストが失敗した場合にアサーションエラーを含めるのはエラーメッセージです。

私はNUnitが例外メッセージのテストをサポートしているとは思っていません。そのようなテストは不必要に脆いと主張します。 本当にのような独自のヘルパーメソッドを記述したい場合は、そうすることができますが、個人的にはそれを推奨しません。 (診断情報を含める場合を除いて、テスト失敗メッセージを指定することはめったにありません。テストが失敗した場合は、そのメッセージはあまり追加されないため、メッセージはあまり追加されません)。

I ものの代わりに、一般的なオーバーロードを使用することをお勧めし、ラムダ式、簡略化のためになります。

Assert.Throws<ArgumentException>(() => new ApplicationArguments(args)); 

(それは道によって、あなたの実際のコードだ場合は、他の問題がある - 引数としてnew[] { "xyz" }に渡してみてください。 ..)

+1

が、メッセージをチェックし、検証する価値はありません。

[Test] [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Invalid ending parameter of the workbook. Please use .xlsx random random")] public void ArgumentsWorkbookNameException() { const string workbookName = "Tester.xls"; var args = new[] { workbookName, "Sheet1", "Source3.csv", "Sheet2", "Source4.csv" }; new ApplicationArguments(args); } 
Riga

+0

@リガ:もしあなたがしたいことができます - しかし、私はそれが私の時間の価値があるとは思わない。私は恐怖が退屈に変わるまでテストを重ねるのが好きです。 *正確な*例外メッセージをテストし、その例外を非常にわずかに有益なものにしたいときは、いつでもテストを変更することに非常に飽きるでしょう。私はそれが有用であるとは思えませんが、 。 –

+1

代わりに、定数を共通の場所またはクラスに格納し、実動コードとテストコードの両方を同じ場所に設定することもできます。メッセージを変更する必要がある場合は、その1つの場所でメッセージを変更します。 – neverendingqs

12

私はJonと "このようなテストは不必要に脆い"と同意します。

1:ただし、例外メッセージをチェックするには、少なくとも2つの方法がある

var exception = Assert.Throws<ArgumentException>(() => new ApplicationArguments(args)); 
Assert.AreEqual("Invalid ending parameter of the workbook. Please use .xlsx random random", exception.Message); 

2:あなたはそのメッセージのためのアサーションを行うことができますので、Assert.Throwsは、例外を返します。また、使用することができますExpectedException属性。しかし、属性は例外をスローするコードだけでなく、テストされたコード全体で例外を待つことに注意してください。したがって、この属性の使用は推奨されません。あなたがテストしている例外は、あなたが望む1と異なるの他のではないことを、

Assert.That(() => new ApplicationArguments(args), 
    Throws.TypeOf<ArgumentException>() 
     .With.Message.EqualTo("Invalid ending parameter of the workbook. Please use .xlsx random random")); 
+3

私は個人的に 'ExpectedExceptionAttribute'を避けるでしょう。 'Assert.Throws'は、エラーが発生する場所を正確に*明示しています。 OP *が本当に*例外メッセージをテストしたいのであれば、彼らは自分自身の 'MoreAssertions.Throws'などを書いた方が良いでしょう。 –

+0

@JonSkeet:確かに、私はその属性について明確にしました。 –

35

はアサーションを作成するために、流れるようなインターフェイスを使用しますあなたのコードのポイント?同じ例外タイプだが、別の場所からのコードでは、実行したくないコードがある可能性があります。
+0

流暢なアサーションは、NUnitのオープンソースアドオンで、https://lukewickstead.wordpress.com/2013/02/09/howto-nunit-fluent-assertions/ にあるサマリーが表示されます。 https://github.com/mvbalaw/FluentAssert –

関連する問題