使用 NUnit Assert.Throws 方法或 ExpectedException 属性?
Posted
技术标签:
【中文标题】使用 NUnit Assert.Throws 方法或 ExpectedException 属性?【英文标题】:Use NUnit Assert.Throws method or ExpectedException attribute? 【发布时间】:2013-02-07 11:55:59 【问题描述】:我发现这些似乎是测试异常的两种主要方法:
Assert.Throws<Exception>(()=>MethodThatThrows());
[ExpectedException(typeof(Exception))]
其中哪一个最好?一个比另一个有优势吗?还是仅仅是个人喜好问题?
【问题讨论】:
第三个选项是流畅的风格:Assert.That(() => MethodThatThrows(), Throws.Exception)
NUnit 版本 3 及更高版本不再支持 ExpectedException
属性,因此对于版本 3+,只有 Assert.Throws
变体是相关的。
为什么会这样?那 Nunit3 决定放弃那个支持?正在谷歌搜索,找不到解释...... JUnit 仍然支持这种方式,不是吗?
【参考方案1】:
我更喜欢 assert.throws,因为它允许我在抛出异常后验证和断言其他条件。
[Test]
[Category("Slow")]
public void IsValidLogFileName_nullFileName_ThrowsExcpetion()
var a = new MyTestObject();
// 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");
【讨论】:
这是更好的答案之一,您想在抛出异常后验证某些东西是否进入错误状态是很常见的。 好答案!但是[Category("Slow")]
和a
是什么意思呢?
您可以使用类别来对您的测试进行分组 - 本示例不需要它 - 在这种情况下,“慢”可能意味着希望能够选择是否每次都运行“慢”测试或仅作为每晚或每周跑步或其他东西的一部分。我相信“a”在技术上是一个语法错误,但它只是您正在测试的对象。【参考方案2】:
如果您使用的是NUnit
的旧版本(),那么您需要使用ExpectedException
。
如果您使用的是 2.5 或更高版本,则可以使用Assert.Throw()
https://github.com/nunit/docs/wiki/Breaking-Changes
使用方法: https://www.nunit.org/index.php?p=exceptionAsserts&r=2.5
【讨论】:
【参考方案3】:您也可以强输入您期望的错误(如旧的属性版本)。
Assert.Throws<System.InvalidOperationException>(() => breakingAction())
【讨论】:
【参考方案4】:主要区别在于:
ExpectedException()
属性在测试方法中任何处发生异常时使测试通过。Assert.Throws()
的使用允许指定 exact
代码的位置,其中预期异常。
NUnit 3.0 完全放弃了对 ExpectedException
的官方支持。
所以,我绝对更喜欢使用Assert.Throws()
方法而不是ExpectedException()
属性。
【讨论】:
这是迄今为止正确的答案。顺便说一句,Assert.Throws() 也返回异常,如果它们对您很重要,它可以允许对异常的属性进行额外检查。 最后回答为什么我不能让 ExpectedException 工作.. 使用版本 3。 这里是链接 github.com/nunit/docs/wiki/Breaking-Changes - ExpectedExceptionAttribute 不再支持。 要将其更改为在 NUnit 3.0 下工作,请将其更改为 the following【参考方案5】:第一个允许您通过多次调用测试多个异常:
Assert.Throws(()=>MethodThatThrows());
Assert.Throws(()=>Method2ThatThrows());
第二个只允许您为每个测试函数测试一个异常。
【讨论】:
一个测试应该只测试一个不同的逻辑位,那么在同一个单元测试中测试两个错误不会被认为是不好的做法吗? @SamuelDavis - 通常你不想在同一个测试中测试不同的案例。但是,多个Assert.Throws
可能会有一些用例。
无论哪种方式,在这里您都可以将异常作为参数获取,这允许您在异常中断言详细信息。此外,使用“预期异常”并不能保护您在另一个方法调用中抛出相同的异常类型。在这里,您针对的是确切的方法,而不是整个测试。即使你的测试应该调用很少的代码,你也永远不会太安全。特别是当代码变得复杂和/或异常过于通用时。诸如“ArgumentNullExceptions”之类的东西可能会被抛出很多,例如使用 ExpectedException 很容易错过。 Assert.Throws 不会错过。以上是关于使用 NUnit Assert.Throws 方法或 ExpectedException 属性?的主要内容,如果未能解决你的问题,请参考以下文章