回答:
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
して、スローされたメッセージが期待されるカルチャを使用していることを確認することです。これは、ローカリゼーションを可能にするリソースとして例外メッセージを保存する場合に役立ちます。
これで、ExpectedException
属性を使用できるようになります。
[Test]
[ExpectedException(typeof(InvalidOperationException),
ExpectedMessage="You can't do that!"]
public void MethodA_WithNull_ThrowsInvalidOperationException()
{
MethodA(null);
}
Assert.Throw
、あなたが正確なラインをターゲットにすることができに興味があります。
Assert.That(myTestDelegate, Throws.ArgumentException
.With.Property("Message").EqualTo("your argument is invalid."));
Assert.That(myTestDelegate, Throws.ArgumentException .With.Property(nameof(ArgumentException.Message)).EqualTo("your argument is invalid."));
Exception.Message
。With.Property
他のオブジェクトにも利用できるので、少なくともこの代替案を追加することをお勧めします。他のオブジェクトにも利用できるため、この場合はコードの安定性が向上します。
これは古くて関連性のある質問で、回答が古いため、現在の解決策を追加します。
public void Test() {
throw new MyCustomException("You can't do that!");
}
[TestMethod]
public void ThisWillPassIfExceptionThrown()
{
var exception = Assert.ThrowsException<MyCustomException>(
() => Test(),
"This should have thrown!");
Assert.AreEqual("You can't do that!", exception.Message);
}
これは using Microsoft.VisualStudio.TestTools.UnitTesting;
永続的な答えを拡張し、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"));
この問題が提起されてから久しぶりですが、最近同じことに遭遇し、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); }));
詳細:http : //phejndorf.wordpress.com/2011/02/21/assert-that-a-particular-exception-has-occured/
新しいNUnitパターンの冗長性に悩まされているので、次のようなものを使用して、個人的にクリーンなコードを作成します。
public void AssertBusinessRuleException(TestDelegate code, string expectedMessage)
{
var ex = Assert.Throws<BusinessRuleException>(code);
Assert.AreEqual(ex.Message, expectedMessage);
}
public void AssertException<T>(TestDelegate code, string expectedMessage) where T:Exception
{
var ex = Assert.Throws<T>(code);
Assert.AreEqual(ex.Message, expectedMessage);
}
次に、使用方法は次のとおりです。
AssertBusinessRuleException(() => user.MakeUserActive(), "Actual exception message");