我是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,其中提到了你描述的所有三种方法(还有一个小的变化)。遗憾的是我以前找不到它: - (。
答案 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")
;