71

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

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

ただし、私は自分のアレンジ、アクト、アサートの手順について非常に明確にする傾向があり、これが課題になります。

私は次のようなことをしていました:

[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 と 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 スタイルのテスターに​​向けて出されます: 私がここでやろうとしているような、ある種の例外検証テストをどのように行いますか?

4

3 に答える 3

68

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

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

于 2015-11-24T15:23:10.287 に答える