我使用MOQ框架進行測試。 我有一個場景,我期望拋出一個錯誤異常。 我如何驗證它被拋出?MOQ - 驗證異常被拋出
public void Koko(List<string?> list)
{
foreach(string? str in list)
{
if (str != null) someProperty.Foo(str);
else throw new FormatException();
}
}
在此先感謝。
我使用MOQ框架進行測試。 我有一個場景,我期望拋出一個錯誤異常。 我如何驗證它被拋出?MOQ - 驗證異常被拋出
public void Koko(List<string?> list)
{
foreach(string? str in list)
{
if (str != null) someProperty.Foo(str);
else throw new FormatException();
}
}
在此先感謝。
請閱讀這個Introduction to Moq。這裏是這樣設置InvalidOperationException
投擲時被調用DoSomething
方法:
mock.Setup(foo => foo.DoSomething()).Throws<InvalidOperationException>();
然後簡單的驗證,如果方法被調用。如果它被稱爲,然後異常發生
mock.Verify(foo => foo.DoSomething());
我不想設置例外。 我想驗證它是否被拋出。 –
@GZ你正試圖驗證Moq是否工作?如果你設置異常拋出,它將被拋出,如果方法被調用。只需驗證方法是否被調用。 –
我會更詳細地解釋場景。也許我的方法是不正確的。 我有一個foreach循環運行在兩個對象上。一個是可用的,一個是空的。 我想驗證兩件事情,第一種方法運行在可用對象上,並且爲空對象拋出異常(在我檢查null的方法中,如果是這樣,則手動拋出異常)。 –
您可以測試一個例外是使用NUnit斷言拋出:
Assert.That(() => testObject.methodToTest(), Throws.TypeOf<FaultException>());
如果您想驗證一個異常被拋出(由你自己的代碼)那麼Moq並不是你選擇的工具。 只需使用其中一個可用的單元測試框架即可。
的xUnit/NUnit的
流利斷言
Action act =() => foo.Bar());
act.ShouldThrow<SomeException>()
好了,所以我解決它以下列方式。
由於異常打破了我的測試,我把方法調用放在try塊中的Because塊中。
然後我可以使用一個簡單的驗證。
感謝所有幫助者...
考慮張貼您的解決方案代碼,其他人可以從中學習或評論。您也可以將此答案標記爲解決方案。 –
聽起來像AlanT有正確的答案。在Moq中,如果你想測試'Foo(string)'會拋出'ArgumentException',你應該使用'ExpectedException' – steve
我可能是錯讀你的意圖,但據我可以看到有沒有必要做任何一個模擬,以檢驗該異常已拋出。
它看起來就像你有一類是需要一個字符串的方法美孚 - 讓我們稱之爲這將InnerClass
public class InnerClass {
public virtual void Foo(string str) {
// do something with the string
}
}
,幷包含一個將InnerClass作爲屬性(someProperty)一類有一個成員科科說一個List <串>作爲參數
public class OuterClass {
private readonly InnerClass someProperty;
public OuterClass(InnerClass someProperty) {
this.someProperty = someProperty;
}
public void Koko(List<string> list) {
foreach (var str in list) {
if (str != null)
someProperty.Foo(str);
else
throw new FormatException();
}
}
}
注:我不能讓列表<字符串? >進行編譯 - 告訴我底層類型(字符串)必須是非空的。 AFAIK,只需要使值類型爲空,引用類型可隱式地爲空。
看起來你想測試一下,如果你傳遞一個字符串列表,其中任何一個字符串都是空的,那麼拋出一個FormatException。
如果是這樣,那麼MOQ的唯一原因是讓我們不必擔心InnerClass的功能。 Foo是一種方法,所以,除非我們使用嚴格的模擬,否則我們可以創建一個沒有其他設置的InnerClass模擬。
有一個屬性[ExpectedException]與我們可以標記我們的測試來驗證異常已被拋出。
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void ExceptionThrown() {
var list = new List<string>() {
"Abel",
"Baker",
null,
"Charlie"
};
var outer = new OuterClass(new Mock<InnerClass>().Object);
outer.Koko(list);
}
如果引發FormatException,則此測試將通過,如果不是,則會失敗。
我不知道ExpectedException屬性,這太棒了!謝謝。 – chrjs
這是真正的答案。謝謝 – CubanTurin
一個老問題,但實際上呈現什麼解決辦法是沒有源代碼,所以這裏就是我所做的:
var correctExceptionThrown = false;
try
{
_myClass.DoSomething(x);
}
catch (Exception ex)
{
if (ex.Message == "Expected message")
correctExceptionThrown = true;
}
Assert.IsTrue(correctExceptionThrown);
注意,而不是檢查的消息,你可以捕捉特定類型的異常(通常最好) 。
顯示你的工作..人們無法閱讀你的想法。請閱讀[常見問題]並[問]也.. –