[英]Unit testing for inner exceptions
我正在使用 Visual Studio 的集成框架編寫一些單元測試。 我需要編寫一些在引發適當異常時通過的測試用例。 問題是我需要測試的異常是嵌套在更一般的異常中的內部異常。 是否有一些簡單的解決方案或者我需要擴展整個功能。 我目前正在使用 [ExpectedException] 屬性,但在這種情況下它不會有什么好處。
我也很好奇當我們使用 [ExpectedException] 時會發生什么,而我們在測試本身也有一些 Assert 邏輯。 是否評估了條件(拋出了異常並且 Assert 語句被證明是有效的)或者在拋出正確的異常后立即通過了測試?
不是一個完整的解決方案,但在 NUnit 中,你可以做這樣的事情:
var ex = Assert.Throws<Exception>(() => thing.ThatThrows());
Assert.That(ex.InnerException, Is.TypeOf<BadException>() );
也許你可以在你的測試框架中?
如果您的框架不支持自定義拋出,您通常有兩種選擇:
我將從第二個解決方案開始。 考慮使用FluentAssertions庫。 它允許你做這樣的事情:
Action deleteUser = () => usersRepository.Delete(new User { Id = null });
deleteUser
.ShouldThrow<UserNotFoundException>()
.WithInnerException<ArgumentNullException>()
.WithInnerMessage("User Id must have value");
您仍將使用 Visual Studio 測試框架,只是您將擁有一個用於流暢斷言的額外庫。
另一方面,首選需要更多的工作,因為手動解決方案通常是這種情況:
try
{
usersRepository.Delete(new User { Id = null });
Assert.Fail("Deleting user with null id should throw");
}
catch (UserNotFoundException ue)
{
Assert.AreEqual(ue.InnerException.Message, "User Id must have value");
}
您將ExpectedException
屬性替換為聲明實際異常實例的自定義代碼。 就像我說的,這是更多的工作,但確實有效。
這是一個老問題,但我想與你們分享我自己的ExpectedInnerExceptionAttribute
實現。 也許對某人有用
public class ExpectedInnerExceptionAttribute : ExpectedExceptionBaseAttribute
{
public ExpectedInnerExceptionAttribute(Type exceptionType)
{
this.ExceptionType = exceptionType;
}
public Type ExceptionType { get; private set; }
protected override void Verify(Exception ex)
{
if (ex != null && ex.InnerException != null
&& ex.InnerException.GetType() == this.ExceptionType)
{
return;
}
throw ex;
}
}
您還可以擴展它以檢查異常消息等。您只需要在驗證方法中添加您自己的邏輯即可。
對於單元測試,我目前使用FluentAssertions 。 自從我學會了它,我再也不想以任何其他方式斷言東西。
對於斷言異常,請查看文檔的這一部分
特別是這部分
Action act = () => subject.Foo2("Hello");
act.ShouldThrow<InvalidOperationException>()
.WithInnerException<ArgumentException>()
.WithInnerMessage("whatever")
我使用它實現了我的解決方案,如下所示。 這是從
AggregateException<\/code>檢查我的自定義異常
ProcessFailureException<\/code>
Func<Task> func = async () => await item.ProcessAsync(context, message);
func.Should().Throw<AggregateException>().WithInnerException<ProcessFailureException>();
只需使用GetAwaiter()
和GetResult()
來檢查內部異常:
Assert.Throws<InnerException>(() => thing.GetAwaiter().GetResult());
例如
Assert.Throws<CommunicationException>(() => thing.GetAwaiter().GetResult());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.