NUnit 3.0和Assert.Throws
我正在用NUnit 3.0编写一些unit testing,而不像v2.x, ExpectedException()
已经从库中删除了。
基于这个答案,我可以肯定地看到试图特别抓住testing的地方的逻辑,一个人期望他们的系统抛出exception(而不是仅仅说“testing中的任何地方”)。
不过,我倾向于对我的“安排”,“行为”和“断言”步骤非常明确,这使得它成为一个挑战。
我曾经这样做过:
[Test, ExpectedException(typeof(FormatException))] public void Should_not_convert_from_prinergy_date_time_sample1() { //Arrange string testDate = "20121123120122"; //Act testDate.FromPrinergyDateTime(); //Assert Assert.Fail("FromPrinergyDateTime should throw an exception parsing invalid input."); }
现在我需要做一些事情:
[Test] public void Should_not_convert_from_prinergy_date_time_sample2() { //Arrange string testDate = "20121123120122"; //Act/Assert Assert.Throws<FormatException>(() => testDate.FromPrinergyDateTime()); }
这不是可怕的,但在我看来,这个法案和声明混淆了。 (很明显,对于这个简单的testing,这并不难,但在更大的testing中可能会更具挑战性)。
我有一个同事build议我完全摆脱Assert.Throws
,只是做一些事情:
[Test] public void Should_not_convert_from_prinergy_date_time_sample3() { //Arrange int exceptions = 0; string testDate = "20121123120122"; //Act try { testDate.FromPrinergyDateTime(); } catch (FormatException) { exceptions++;} //Assert Assert.AreEqual(1, exceptions); }
在这里,我坚持严格的AAA格式,但代价更大。
所以我的问题出现在AAA风格的testing人员:你会怎么做一些exceptionvalidationtesting,就像我在这里做的那样?
我明白你来自哪里,尽pipe我不介意在这种情况下将Act / Assert步骤结合起来。
我能想到的唯一的事情就是将实际的委托(这里FromPrinergyDateTime
)作为“行为”步骤存储到一个variables中,然后断言:
[Test] public void Should_not_convert_from_prinergy_date_time_sample2() { //Arrange string testDate = "20121123120122"; //Act ActualValueDelegate<object> testDelegate = () => testDate.FromPrinergyDateTime(); //Assert Assert.That(testDelegate, Throws.TypeOf<FormatException>()); }
我知道“行为”步骤并不是真正的行为,而是定义了行为。 但是,它明确划定了正在testing的操作。
在C#7中,还有另一种select(尽pipe与现有的答案非常相似):
[Test] public void Should_not_convert_from_prinergy_date_time_sample2() { void CheckFunction() { //Arrange string testDate = "20121123120122"; //Act testDate.FromPrinergyDateTime(); } //Assert Assert.Throws(typeof(Exception), CheckFunction); }
博客文章的主题
您可以在NUnit 3中创build一个自定义属性。下面是如何创build[ExpectedException]属性的示例代码(ExpectedExceptionExample显示如何为NUnit实现自定义属性) https://github.com/nunit/nunit-csharp-samples