답변:
Assert.Throws
throw 된 예외를 반환하여 예외를 주장 할 수 있습니다.
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
은 던져진 메시지가 예상 문화권을 사용하고 있는지 확인하기 위해 테스트 방법을 장식하는 것입니다. 예외 메시지를 지역화 할 수있는 리소스로 저장하면 작동합니다.
이제 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");