1. ホーム
  2. c#

[解決済み】Assert.Throwsを使って、例外の型をアサーションするには?

2022-04-01 19:34:34

質問

を使用するにはどうすればよいのでしょうか? Assert.Throws を使用して、例外の型と実際のメッセージの文言をアサートできますか?

このようなものです。

Assert.Throws<Exception>(
    ()=>user.MakeUserActive()).WithMessage("Actual exception message")

私がテストしているメソッドは、異なるメッセージを持つ同じタイプの複数のメッセージを投げるので、コンテキストに応じて正しいメッセージが投げられることをテストする方法が必要です。

どのように解決するのですか?

Assert.Throws はスローされた例外を返し、その例外に対してアサートすることができます。

var ex = Assert.Throws<Exception>(() => user.MakeUserActive());
Assert.That(ex.Message, Is.EqualTo("Actual exception message"));

そのため、例外が発生しなかったり、間違った型の例外が発生した場合、最初の Assert.Throws のアサーションは失敗します。しかし、正しい型の例外がスローされた場合は、変数に保存しておいた実際の例外に対してアサーションを行うことができます。

このパターンを使用すると、例外メッセージ以外のものに対してもアサーションを行うことができます。 ArgumentException と派生して、パラメータ名が正しいかどうかをアサーションすることができます。

var ex = Assert.Throws<ArgumentNullException>(() => foo.Bar(null));
Assert.That(ex.ParamName, Is.EqualTo("bar"));

これらのアサートを行うために、fluent API を使用することもできます。

Assert.That(() => foo.Bar(null), 
Throws.Exception
  .TypeOf<ArgumentNullException>()
  .With.Property("ParamName")
  .EqualTo("bar"));

または、その代わりに

Assert.That(
    Assert.Throws<ArgumentNullException>(() =>
        foo.Bar(null)
    .ParamName,
Is.EqualTo("bar"));

例外メッセージをアサーションするときのちょっとしたコツは、テストメソッドを SetCultureAttribute を使用して、スローされたメッセージが期待されるカルチャを使用していることを確認します。これは、ローカライズを可能にするために、例外メッセージをリソースとして保存する場合に、重要になります。