NUnit的ExpectedExceptionAttribute是否只能测试是否会引发异常?

时间:2008-11-02 22:48:33

标签: c# exception nunit

我是C#和NUnit的新手。

在Boost.Test中有一系列BOOST_*_THROW个宏。在Python的测试模块中有TestCase.assertRaises方法。

据我了解,在C#中使用NUnit(2.4.8)进行异常测试的唯一方法是使用ExpectedExceptionAttribute

为什么我更喜欢ExpectedExceptionAttribute - 比方说 - Boost.Test的方法?这个设计决定背后有什么推理?为什么在C#和NUnit的情况下会更好?

最后,如果我决定使用ExpectedExceptionAttribute,在引发异常并捕获异常后,如何进行一些额外的测试?假设我想测试需求,说明在某个setter引发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() );
}

编辑:感谢您的回答。今天,我发现了一个它是测试 blog entry,其中提到了你描述的所有三种方法(还有一个小的变化)。遗憾的是我以前找不到它: - (。

5 个答案:

答案 0 :(得分:13)

我很惊讶我还没有看到这种模式。 David Arno非常相似,但我更喜欢这个的简单性:

try
{
    obj.SetValueAt(-1, "foo");
    Assert.Fail("Expected exception");
}
catch (IndexOutOfRangeException)
{
    // Expected
}
Assert.IsTrue(obj.IsValid());

答案 1 :(得分:10)

如果你可以使用NUnit 2.5那里有一些不错的helpers

Assert.That( delegate { ... }, Throws.Exception<ArgumentException>())

答案 2 :(得分:4)

MbUnit语法是

Assert.Throws<IndexOutOfRangeException>(delegate {
    int[] nums = new int[] { 0, 1, 2 };
    nums[3] = 3;
});

答案 3 :(得分:2)

我一直采用以下方法:

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

assert.IsFalse(success);

...

答案 4 :(得分: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")
;