web-dev-qa-db-ja.com

NUnit 3.0およびAssert.Throws

NUnit 3.0でいくつかの単体テストを書いていますが、v2.xとは異なり、ExpectedException()はライブラリから削除されました。

this answerに基づいて、テストのどこでシステムが例外をスローすると予想されるかを具体的にキャッチしようとするロジックを明確に見ることができます(「テストのどこでも」と言うのではなく)。

ただし、アレンジ、アクト、およびアサートの手順については非常に明確になりがちなので、これが課題になります。

以前は次のようなことをしていました。

[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());
}

これはひどいことではありませんが、私の意見では、Act and Assertを混乱させます。 (明らかに、この単純なテストの場合、従うのは難しくありませんが、大規模なテストではより難しいかもしれません)。

私は同僚に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スタイルのテスターに​​行きます。ここでやろうとしているような、ある種の例外検証テストをどうやってやるのですか?

62
Killnine

この場合、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>());
}

私は、「行為」ステップは実際に行為ではなく、むしろ行為が何であるかを定義していると思います。ただし、どのアクションがテストされているかは明確に示されています。

61
Patrick Quirk

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);
}

主題に関するブログ投稿

22
Paul Michaels

NUnit 3でカスタム属性を作成できます。[ExpectedException]属性を作成するサンプルコードを次に示します。(ExpectedExceptionExampleは、NUnitのカスタム属性を実装する方法を示します) https://github.com/nunit/nunit -csharp-samples

6
Matt Allen