SOに関する別の質問+回答を参照する上記のブロックには、ここに適用される正解は含まれていません!
単体テストに使用されるメソッドがあります。このメソッドの目的は、(デリゲートによって参照される) コードの一部が特定の例外を確実にスローするようにすることです。その例外がスローされた場合、単体テストは成功します。例外がスローされない場合、または別のタイプの例外がスローされる場合、単体テストは失敗します。
/// <summary>
/// Checks to make sure that the action throws a exception of type TException.
/// </summary>
/// <typeparam name="TException">The type of exception expected.</typeparam>
/// <param name="action">The code to execute which is expected to generate the exception.</param>
public static void Throws<TException>(Action action)
where TException : Exception
{
try
{
action();
}
catch (TException)
{
return;
}
catch (Exception ex)
{
Assert.Fail("Wrong exception was thrown. Exception of type " + ex.GetType() + " was thrown, exception of type " + typeof(TException) + " was expected.");
}
Assert.Fail("No exception was thrown. Exception of type " + typeof(TException) + " was expected.");
}
次の呼び出しは成功するはずですが、失敗します。
int result = 0;
Throws<DivideByZeroException>(() => result = result / result);
タイプの予期される例外TException
がスローされると、最初のキャッチではなく、常に 2 番目のキャッチによってキャッチされます。どうしてこれなの?
もちろん、1 つのキャッチで回避策を使用して、ex
タイプが であるかどうかをテストできますTException
。このコードがコンパイルされる理由を知りたい/理解したいだけですが、単純な(決して?) 動作します。
編集
要求に応じて「動作する」デモ:
using System;
namespace GenericExceptionDemo
{
class Program
{
static void Main(string[] args)
{
int n = 0;
Catch<DivideByZeroException>(() => n = n / n);
}
static public void Catch<TException>(Action action)
where TException: Exception
{
try
{
action();
Console.WriteLine("No exception thrown. !!!Fail!!!");
}
catch (TException)
{
Console.WriteLine("Expected exception thrown. PASS!");
}
catch(Exception ex)
{
Console.WriteLine("An unexpected exception of type " + ex.GetType() + " thrown. !!!FAIL!!!");
}
}
}
}