2013-02-21 52 views
121

我发现,这些似乎是测试的例外情况的主要有两种方式:使用NUnit Assert.Throws方法或ExpectedException属性?

Assert.Throws<Exception>(()=>MethodThatThrows()); 

[ExpectedException(typeof(Exception))] 

其中哪些是最好的?一个人比另一个人有优势吗?还是仅仅是个人喜好的问题?

+1

一个第三选择是流畅的风格:'Assert.That( ()=> MethodThatThrows(),Throws.Exception)' – Schneider 2016-10-07 02:37:14

回答

71

第一个允许您测试多个异常,多次调用:

Assert.Throws(()=>MethodThatThrows()); 
Assert.Throws(()=>Method2ThatThrows()); 

第二只允许您测试每个测试功能的一个例外。

+19

测试应该只测试一个不同的逻辑位,所以不会在同一个单元测试中测试两个错误被认为是不好的做法? – SamuelDavis 2013-02-22 00:03:55

+5

@SamuelDavis - 一般来说,你不想在同一个测试中测试不同的情况。但是,可能会有一些用于多个'Assert.Throws'的用例。 – 2013-02-22 00:11:57

+2

无论哪种方式,在这里你都会得到一个异常作为参数,它允许你在异常中断言细节。 此外,使用“预期异常”不会保护您在另一个方法调用中引发的相同异常类型。在这里,你的目标是确切的方法,而不是整个测试。即使你的测试应该调用很少的代码,但你永远不会太安全。特别是当代码变得复杂和/或异常过于通用时。 像“ArgumentNullExceptions”这样的东西可能会被抛出很多,例如使用ExpectedException可能会很容易丢失。 Assert.Throws不会错过它。 – 2016-06-02 21:51:41

28

我更喜欢assert.throws,因为它允许我在抛出异常之后验证并断言其他条件。

[Test] 
    [Category("Slow")] 
    public void IsValidLogFileName_nullFileName_ThrowsExcpetion() 
    { 
     // the exception we expect thrown from the IsValidFileName method 
     var ex = Assert.Throws<ArgumentNullException>(() => a.IsValidLogFileName("")); 

     // now we can test the exception itself 
     Assert.That(ex.Message == "Blah"); 

    } 
+0

这是更好的答案之一,你想验证在抛出异常之后进入错误状态的情况很常见。 – 2016-04-01 05:47:19

226

的主要区别在于:

ExpectedException()属性使得如果在发生异常在测试方法中的任何地方测试通过。
Assert.Throws()的用法允许指定exact代码的位置,其中预期有异常。

NUnit 3.0完全放弃对ExpectedException的官方支持。

所以,我绝对倾向于使用Assert.Throws()方法而不是ExpectedException()属性。

+4

这是迄今为止正确的答案。顺便提一下,Assert.Throws()也会返回异常,如果它们对您有影响,它可以允许额外检查异常的属性。 – perfectionist 2015-05-29 18:14:11

+0

最后回答为什么我不能得到ExpectedException与版本3一起工作。 – johnyTee 2017-03-20 21:46:00

+1

这里是链接https://github.com/nunit/docs/wiki/Breaking-Changes - 不再支持ExpectedExceptionAttribute。 – Spirit 2017-12-18 16:54:23

9

您也可以强键输入您期待的错误(如旧的attrib版本)。

Assert.Throws<System.InvalidOperationException>(() => breakingAction())