私は遭遇した問題を分離して実証する簡単なテストプログラムを考案することを提案した著名なJohn Skeet氏の要請により、この質問を新たに投稿しています。この質問はthis oneから生まれました。とても親しみがあるように聞こえたら私を許してください。あなたはこの質問に関する追加の詳細を潜在的に収集することができます。NUnit:なぜAssert.Throwsしません<T>私のArgumentNullExceptionをキャッチですか?
NUnit 2.5.9からAssert.Throws<T>
の問題が発生しました。場合によっては、例外をTestDelegateによって呼び出されたメソッドでスローすることができません。私は以下のコードでこの振る舞いを再現可能な方法で固定しています。 。(™これは、確かにあってもよいの場合は、私のマシンで失敗するものの
エラーを再現するために、私は2つのC#のDLLプロジェクトとソリューションを作成しました:
- 最初は1つのクラスを含んでいます、このメソッドは、
SqlCommand
を作成するために必要なロジックをカプセル化し、そのパラメータを設定し、ExecuteScalar
を呼び出す拡張メソッドです。 - 2つ目は、2つのメソッド最初のDLLのメソッドが期待どおりに動作しているかどうかをテストします。 NUnitフレームワークを参照してください。他のアセンブリは参照されません。私は、デバッガでテストをステップ実行すると
、私は次のことを守ってください。
Assert.Throws
は正しくExecuteScalar<T>
拡張メソッドを呼び出します。- パラメータ値は、期待どおりにNULLです。
ExecuteScalar<T>
は、ヌル値のパラメータをテストします。- デバッガはヒットし、
throw new ArgumentNullException(...)
を含む行を実行します。 throw
の実行後、アプリケーションの制御はすぐにAssert.Throws
に転送されません。代わりに、それはExecuteScalar<T>
の次の行に続きます。- 次のコード行が実行されるとすぐに、デバッガがブレークし、「引数null例外がユーザーコードによって処理されませんでした」というエラーが表示されます。
この動作を分離するソースコードを以下に示します。
拡張メソッド
namespace NUnit_Anomaly
{
using System;
using System.Data;
using System.Data.SqlClient;
public static class Class1
{
public static T ExecuteScalar<T>(this SqlConnection connection, string sql)
{
if (connection == null)
{
throw new ArgumentNullException("connection");
}
if (sql == null)
{
throw new ArgumentNullException("sql");
}
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = sql;
return (T)command.ExecuteScalar();
}
}
}
}
テストケース
namespace NUnit_Tests
{
using System;
using System.Data.SqlClient;
using System.Diagnostics;
using NUnit.Framework;
using NUnit_Anomaly;
[TestFixture]
public class NUnitAnomalyTest
{
[Test]
public void ExecuteDataSetThrowsForNullConnection()
{
Assert.Throws<ArgumentNullException>(() => ((SqlConnection)null).ExecuteScalar<int>(null));
}
[Test]
public void ExecuteDataSetThrowsForNullSql()
{
const string server = "MY-LOCAL-SQL-SERVER";
const string instance = "staging";
string connectionString = String.Format("Data Source={0};Initial Catalog={1};Integrated Security=True;",
server,
instance);
using (var connection = new SqlConnection(connectionString))
{
Assert.Throws<ArgumentNullException>(() => connection.ExecuteScalar<int>(null));
}
}
}
}
正味の効果は、とき、彼らはいけないテストが失敗していることです。私の理解の中で、Assert.Throws<T>
は私の例外を捕らえるべきで、テストは合格しなければなりません。
UPDATE
私はハンスの助言を取り、例外]ダイアログを確認しました。私は例外を投げて例外をスローしていませんでしたが、私は未処理のユーザ例外を壊していました。どうやら、例外がスローされたときにデバッガがIDEに壊れてしまうのです。チェックボックスをオフにすると問題が解決され、Assert.Throws<T>
が選択されました。しかし、これをやっていないと、F5を押して実行を続けることはできません。例外はNullReferenceException
になります。
ここで問題は次のとおりです。プロジェクトごとに例外ブレークを設定できますか?私はテストをしているときだけこれをしたいが、一般的ではない。
Debug + Throwチェックボックスがオフになっていることを確認してください。 –
@ Hans Passant:私は、Thrownチェックボックスのどれもチェックされていないことを確認しました。 –