NUnit 3.0和Assert.Throws

Kil*_*ine 64 c# nunit unit-testing

我正在使用NUnit 3.0编写一些单元测试,并且与v2.x不同,ExpectedException()它已从库中删除.

根据这个答案,我绝对可以看到试图捕捉特定位置的逻辑,在测试中人们期望他们的系统抛出异常(而不是仅仅说"测试中的任何地方").

但是,我倾向于非常清楚我的Arrange,Act和Assert步骤,这使它成为一个挑战.

我曾经做过类似的事情:

[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.");
}
Run Code Online (Sandbox Code Playgroud)

现在我需要做一些事情:

[Test]
public void Should_not_convert_from_prinergy_date_time_sample2()
{
    //Arrange
    string testDate = "20121123120122";

    //Act/Assert
    Assert.Throws<FormatException>(() => testDate.FromPrinergyDateTime());
}
Run Code Online (Sandbox Code Playgroud)

这并不可怕,但在我看来,这种行为和断言是混乱的.(显然,对于这个简单的测试,它并不难理解,但在更大的测试中可能更具挑战性).

我有一位同事建议我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);
}
Run Code Online (Sandbox Code Playgroud)

在这里,我坚持严格的AAA格式,但代价是更加臃肿.

所以我的问题出现在AAA风格的测试人员身上:你会如何进行某种异常验证测试,就像我在这里尝试一样?

Pat*_*irk 61

我知道你来自哪里,即使我不介意在这种情况下结合Act/Assert步骤.

我唯一能想到的是将实际委托(此处FromPrinergyDateTime)存储到变量中作为"act"步骤,然后断言它:

[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>());
}
Run Code Online (Sandbox Code Playgroud)

我认为"行为"步骤并非真正起作用,而是定义行动的内容.但是,它确实清楚地描述了正在测试的操作.

  • 男人,希望我明白那里发生了什么 (3认同)
  • 尽管如此,仍然没有真正"表演".只是声明你打算如何行事. (2认同)

Pau*_*els 24

在C#7中,还有另一种选择(尽管与现有答案非常相似):

[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);
}
Run Code Online (Sandbox Code Playgroud)

关于这个主题的博客文章

  • 因为"你可以在c#中实际做到这一点"的因素而提升 (5认同)

Mat*_*len 6

您可以在NUnit 3中创建自定义属性.以下是如何创建[ExpectedException]属性的示例代码.(ExpectedExceptionExample显示如何为NUnit实现自定义属性) https://github.com/nunit/nunit-csharp-samples