5

私は C# と NUnit の初心者です。

Boost.Test には、BOOST_*_THROWマクロのファミリがあります。Python のテスト モジュールにはTestCase.assertRaisesメソッドがあります。

私が理解している限り、NUnit (2.4.8) を使用した C# では、例外テストを行う唯一の方法は を使用することExpectedExceptionAttributeです。

ExpectedExceptionAttributeBoost.Testのアプローチよりも優先する必要があるのはなぜですか? この設計上の決定の背後には、どのような理由が考えられるでしょうか? C# と NUnit の場合、なぜそれが優れているのでしょうか?

最後に、使用することにした場合ExpectedExceptionAttribute、例外が発生してキャッチされた後に追加のテストを行うにはどうすればよいですか? セッターが発生した後にオブジェクトが有効でなければならないという要件をテストしたいとしましょうSystem.IndexOutOfRangeException。次のコードをコンパイルして期待どおりに動作させるには、どのように修正しますか?

[Test]
public void TestSetterException()
{
    Sth.SomeClass obj = new SomeClass();

    // Following statement won't compile.
    Assert.Raises( "System.IndexOutOfRangeException",
                   obj.SetValueAt( -1, "foo" ) );

    Assert.IsTrue( obj.IsValid() );
}

編集:回答ありがとうございます。今日、It's the Tests ブログ エントリで、あなたが説明した 3 つの方法すべて (およびもう 1 つの小さなバリエーション) が言及されているのを見つけました。以前は見つけられなかったのが残念です:-(。

4

5 に答える 5

13

このパターンがまだ言及されていないことに驚いています。David Arno のものは非常に似ていますが、私はこれの単純さを好みます。

try
{
    obj.SetValueAt(-1, "foo");
    Assert.Fail("Expected exception");
}
catch (IndexOutOfRangeException)
{
    // Expected
}
Assert.IsTrue(obj.IsValid());
于 2008-11-02T23:03:12.757 に答える
10

NUnit 2.5 を使用できる場合は、いくつかの優れたヘルパーがあります。

Assert.That( delegate { ... }, Throws.Exception<ArgumentException>())
于 2008-11-02T22:55:18.747 に答える
4

MbUnit の構文は次のとおりです。

Assert.Throws<IndexOutOfRangeException>(delegate {
    int[] nums = new int[] { 0, 1, 2 };
    nums[3] = 3;
});
于 2008-11-02T23:01:01.857 に答える
2

好みの構文:

Assert.Raises( "System.IndexOutOfRangeException",
               obj.SetValueAt( -1, "foo" ) );

いずれにしても C# では機能しません。obj.SetValueAt が評価され、結果が Assert.Raises に渡されます。SetValue が例外をスローした場合、Assert.Raises に入ることができません。

それを行うヘルパーメソッドを書くことができます:

void Raises<T>(Action action) where T:Exception {
   try {
      action();
      throw new ExpectedException(typeof(T));
   catch (Exception ex) {
      if (ex.GetType() != typeof(T)) {
         throw;
      }
   }
}

これにより、次のような構文が可能になります。

Assert.Raises<System.IndexOutOfRangeException>(() => 
  obj.SetValueAt(-1, "foo")
;
于 2008-11-02T23:44:20.957 に答える
2

私は常に次のアプローチを採用してきました。

bool success = true;
try {
    obj.SetValueAt(-1, "foo");
} catch () {
    success = false;
}

assert.IsFalse(success);

...
于 2008-11-02T22:55:41.303 に答える