2013-04-17 92 views
13

我使用MOQ框架進行測試。 我有一個場景,我期望拋出一個錯誤異常。 我如何驗證它被拋出?MOQ - 驗證異常被拋出

public void Koko(List<string?> list) 
{ 
    foreach(string? str in list) 
    { 
     if (str != null) someProperty.Foo(str); 
     else throw new FormatException(); 
    } 
} 

在此先感謝。

+0

顯示你的工作..人們無法閱讀你的想法。請閱讀[常見問題]並[問]也.. –

回答

6

請閱讀這個Introduction to Moq。這裏是這樣設置InvalidOperationException投擲時被調用DoSomething方法:

mock.Setup(foo => foo.DoSomething()).Throws<InvalidOperationException>(); 

然後簡單的驗證,如果方法被調用。如果它被稱爲,然後異常發生

mock.Verify(foo => foo.DoSomething()); 
+0

我不想設置例外。 我想驗證它是否被拋出。 –

+0

@GZ你正試圖驗證Moq是否工作?如果你設置異常拋出,它將被拋出,如果方法被調用。只需驗證方法是否被調用。 –

+0

我會更詳細地解釋場景。也許我的方法是不正確的。 我有一個foreach循環運行在兩個對象上。一個是可用的,一個是空的。 我想驗證兩件事情,第一種方法運行在可用對象上,並且爲空對象拋出異常(在我檢查null的方法中,如果是這樣,則手動拋出異常)。 –

6

您可以測試一個例外是使用NUnit斷言拋出:

Assert.That(() => testObject.methodToTest(), Throws.TypeOf<FaultException>()); 
0

好了,所以我解決它以下列方式。

由於異常打破了我的測試,我把方法調用放在try塊中的Because塊中。

然後我可以使用一個簡單的驗證。

感謝所有幫助者...

+4

考慮張貼您的解決方案代碼,其他人可以從中學習或評論。您也可以將此答案標記爲解決方案。 –

+2

聽起來像AlanT有正確的答案。在Moq中,如果你想測試'Foo(string)'會拋出'ArgumentException',你應該使用'ExpectedException' – steve

18

我可能是錯讀你的意圖,但據我可以看到有沒有必要做任何一個模擬,以檢驗該異常已拋出。

它看起來就像你有一類是需要一個字符串的方法美孚 - 讓我們稱之爲這將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,則此測試將通過,如果不是,則會失敗。

+0

我不知道ExpectedException屬性,這太棒了!謝謝。 – chrjs

+0

這是真正的答案。謝謝 – CubanTurin

5

一個老問題,但實際上呈現什麼解決辦法是沒有源代碼,所以這裏就是我所做的:

var correctExceptionThrown = false; 

try 
{ 
    _myClass.DoSomething(x); 
} 
catch (Exception ex) 
{ 
    if (ex.Message == "Expected message") 
     correctExceptionThrown = true; 
}      

Assert.IsTrue(correctExceptionThrown); 

注意,而不是檢查的消息,你可以捕捉特定類型的異常(通常最好) 。