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スタイルのテスターに行きます。ここでやろうとしているような、ある種の例外検証テストをどうやってやるのですか?
この場合、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>());
}
私は、「行為」ステップは実際に行為ではなく、むしろ行為が何であるかを定義していると思います。ただし、どのアクションがテストされているかは明確に示されています。
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);
}
NUnit 3でカスタム属性を作成できます。[ExpectedException]属性を作成するサンプルコードを次に示します。(ExpectedExceptionExampleは、NUnitのカスタム属性を実装する方法を示します) https://github.com/nunit/nunit -csharp-samples