C# 我怎么能期待 Assert.AreEqual 中的异常?
Posted
技术标签:
【中文标题】C# 我怎么能期待 Assert.AreEqual 中的异常?【英文标题】:C# How I can expect a exception in Assert.AreEqual? 【发布时间】:2015-07-31 09:22:56 【问题描述】:示例:
Assert.AreEqual(**null**, Program.nDaysMonth(5, -10), "Error nDaysMonth, Month may -10.");
我期待一个例外。我怎么能期待 Assert.AreEqual 中的异常?
谢谢。
【问题讨论】:
如果您期望异常,为什么要使用Assert
?为什么不用ExpectedException
来装饰你的方法呢?
请参阅:***.com/questions/933613/… - 如果这不能满足您的需求,请添加额外信息说明为什么不这样做。
您是在问如何编写单元测试来验证Program.nDaysMonth(5, -10)
是否抛出异常?
@YuvalItzchakov 你不应该使用 ExpectedException 属性,它不好。而不是这个使用 Assert.Throws 方法。然后你就知道异常发生在哪里,测试写得更好。
请指定您正在使用的单元测试框架 - 我们无法仅从您的代码 sn-p 中看出这一点。
【参考方案1】:
如果您使用的是 Microsoft 测试框架,则需要使用 ExpectedExceptionAttribute 装饰方法:
[TestClass]
public class UnitTest1
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestMethod1()
//Do whatever causes the exception here
然后测试将通过或失败取决于是否抛出异常。
但是,正如 Jon 在下面指出的那样,请找到一个支持 Assert.Throws
或其中一些变体的测试框架。使用预期的异常进行装饰可能会导致代码中的错误传递或其他问题,具体取决于您正在执行的操作,并且在方法中引发异常后很难执行任何操作。使用功能齐全的框架将显着提高测试质量。
我推荐 NUnit,http://www.nunit.org/
或者还有XUnit之类的https://github.com/xunit/xunit
或其他几十个:http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#.NET_programming_languages
【讨论】:
这是一个坏主意(IMO),原因在我的回答中的评论中列出。将预期异常的范围限制为 lambda 表达式是更更干净的 IMO。 我同意,但是不要自己动手,只使用 MS 可用的东西(用于快速测试),这是唯一的选择。在我看来,如果它是在该方法中进行的唯一测试,那么它很重要。 那么你几乎需要用属性来装饰方法,不是吗?那只是如果您不想费心重新实现Assert.Throws
- 这非常简单,并且使您的所有其余测试更加清晰,IMO。我肯定会建议这样做(或切换到过去没有卡住的测试框架......)
谢谢。我用 [ExpectedException] 做到了。【参考方案2】:
你不用Assert.AreEqual
,你用Assert.Throws
:
Assert.Throws<ArgumentOutOfRangeException>(() => Program.nDaysMonth(5, -10));
这会检查是否抛出了正确的异常。如果要添加更多的断言,可以使用返回值:
var exception = Assert.Throws<ArgumentOutOfRangeException>(...);
Assert.AreEqual("Foo", exception.Message); // Or whatever
这至少适用于 NUnit 和 xUnit;如果您使用不同的测试框架,您应该寻找类似的功能。如果它不存在,我建议您自己实现它——它很容易做到,而且比替代品(try/catch 块,或方法范围的ExpectedException
属性)更干净。或者,如果可以的话,更改单元测试框架...
我还强烈建议您开始遵循正常的 .NET 命名约定 - nDaysMonth
不是一个好的方法名称...
一些框架支持使用 [ExpectedException]
属性来装饰方法 - 我建议 反对 使用它:
-
这使得测试不清楚您希望在哪里引发异常。
如果在测试方法的其他地方抛出异常(即您的代码已损坏),测试仍将通过。
抛出异常后,您无法执行任何其他操作。
您无法检查有关异常的任何其他内容。
【讨论】:
Assert
没有名为 Throws
的方法。还是我错过了什么?
@oleksii: 1) 这使得测试不清楚您希望在哪里抛出异常。 2)如果在测试方法的其他地方抛出异常(即您的代码被破坏),测试仍然会通过。 3) 抛出异常后,你不能做任何其他事情。 4)您无法检查有关异常的任何其他内容。基本上,这是个坏主意。
@YuvalItzchakov:没有一个单独的 Assert
类用于单元测试 - NUnit 中的一个,xUnit 中的一个,Microsoft Test 中的一个,等等。
@YuvalItzchakov:我在回答中已经明确说明了这一点。
@Jesús:你读过我为什么使用ExpectedException
是个坏主意吗?以上是关于C# 我怎么能期待 Assert.AreEqual 中的异常?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Assert.AreEqual(1.0, double.NaN, 1.0) 通过?
NUnit Assert.AreEqual DateTime 容差