使用NUnit Assert.Throws方法还是ExpectedException属性?


146

我发现这些似乎是测试异常的两种主要方法:

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

[ExpectedException(typeof(Exception))]

其中哪一个最好?一个提供其他优点吗?还是仅仅是个人喜好问题?


3
第三种选择是流畅的风格:Assert.That(() => MethodThatThrows(), Throws.Exception)
Jack Ukleja

1
NUnit 3和更高版本不再支持该ExpectedException属性,因此对于3+版本,仅该Assert.Throws变体是相关的。
joanlofe

为什么会这样呢?Nunit3决定放弃该支持?在四处搜寻并且找不到解释... JUnit仍然支持这种方式,不是吗?
ahaaman '19

Answers:


92

第一个允许您通过多个调用来测试多个异常:

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

第二个只允许您测试每个测试功能的一个异常。


25
一个测试只应该测试一个不同的逻辑位,那么在同一个单元测试中测试两个错误是否被认为是不正确的做法?
SamuelDavis

5
@SamuelDavis-通常,您不想在同一测试中测试不同的案例。但是,可能有多个用例Assert.Throws
x x

3
无论哪种方式,您都可以在这里将异常作为参数获取,从而可以声明异常的详细信息。同样,使用“预期异常”不会保护您在另一个方法调用中抛出的相同异常类型。在这里,您指定的是确切方法,而不是整个测试。即使您的测试只需要调用很少的代码,也永远不会太安全。尤其是当代码变得复杂和/或异常过于笼统时。诸如“ ArgumentNullExceptions”之类的东西可能会抛出很多,例如,使用ExpectedException很容易错过。声明。投掷不会错过。
吉尔·桑德

254

主要区别在于:

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

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

因此,我绝对更喜欢使用Assert.Throws()方法而不是ExpectedException()属性。


7
到目前为止,这是正确的答案。顺便说一句,Assert.Throws()也返回异常,如果异常对您很重要,它可以允许对异常属性进行其他检查。
完美主义者

1
最后回答为什么我无法使ExpectedException与版本3一起工作
。– JanT


为了NUnit的3.0下更改此工作,将其更改为以下
安德烈Krasutski

38

我更喜欢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");

    }

这是更好的答案之一,在抛出异常后要验证某事物是否进入错误状态是很常见的。
Rhys Bevilaqua

11

您也可以强行键入您期望的错误(例如旧的attrib版本)。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.