276

Assert.Throws例外のタイプと実際のメッセージの文言をアサートするにはどうすればよいですか?

このようなもの:

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

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

4

9 に答える 9

505

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"));

これらのアサーションを行うために流暢な 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て、スローされたメッセージが予期されるカルチャを使用していることを確認することです。これは、例外メッセージをリソースとして保存してローカライズできるようにする場合に役立ちます。

于 2009-10-22T19:49:19.593 に答える
25

ExpectedException属性を使用できるようになりました。

[Test]
[ExpectedException(typeof(InvalidOperationException), 
 ExpectedMessage="You can't do that!"]
public void MethodA_WithNull_ThrowsInvalidOperationException()
{
    MethodA(null);
}
于 2010-12-23T10:06:11.743 に答える
3

永続的な回答を拡張し、NUnitの機能をさらに提供するには、次のようにします。

public bool AssertThrows<TException>(
    Action action,
    Func<TException, bool> exceptionCondition = null)
    where TException : Exception
{
    try
    {
        action();
    }
    catch (TException ex)
    {
        if (exceptionCondition != null)
        {
            return exceptionCondition(ex);
        }
        return true;
    }
    catch
    {
        return false;
    }

    return false;
}

例:

// No exception thrown - test fails.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => {}));

// Wrong exception thrown - test fails.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new ApplicationException(); }));

// Correct exception thrown - test passes.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new InvalidOperationException(); }));

// Correct exception thrown, but wrong message - test fails.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new InvalidOperationException("ABCD"); },
        ex => ex.Message == "1234"));

// Correct exception thrown, with correct message - test passes.
Assert.IsTrue(
    AssertThrows<InvalidOperationException>(
        () => { throw new InvalidOperationException("1234"); },
        ex => ex.Message == "1234"));
于 2013-03-08T20:41:00.260 に答える
2

私は最近同じことに遭遇し、MSTest に次の関数を提案します。

public bool AssertThrows(Action action) where T : Exception
{
    try {action();
}
catch(Exception exception)
{
    if (exception.GetType() == typeof(T))
        return true;
}
    return false;
}

使用法:

Assert.IsTrue(AssertThrows<FormatException>(delegate{ newMyMethod(MyParameter); }));

Assert には、特定の例外が発生したこと (MSTest の Assert.Throws)がさらにあります。

于 2011-03-02T07:28:46.983 に答える