2010-11-02 24 views
30

我有一個接口定義爲MOQ - 建立了一種基於

interface IMath 
{ 
AddNumbersBetween(int lowerVal, int upperVal); 
} 

我可以設置一個基本起訂量爲上述如下參數值(多個參數):

Mock<IMath> mock = new Mock<IMath>();  
mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())); 

呼叫它

mock.Object.AddNumbersBetween(1,4); 

,然後驗證它被稱爲

mock.Verify(m => m.AddNumbersBetween(1,4), Times.AtleastOnce()); 

我無法弄清楚如何設置方法AddNumbersBetween這樣,如果upperVal是低於lowerVal拋出一個異常

mock.Object.AddNumbersBetween(4,1);//should throw an exception 

本質上尋找類似:

mock.Setup(foo => foo.AddNumbersBetween("arg1 is higher than arg2")).Throws<ArgumentException>(); 
+1

我會推薦簡單地用Callback實現異常拋出邏輯,因爲這可以讓你完全訪問這兩個參數。據我所知,參數匹配子句只能執行基於單個參數的邏輯。 – 2010-11-02 19:07:06

回答

62

我知道這是一歲,但我發現了一種利用與起訂量的最新版本的多個參數至少:

mock.Setup(x => x.Method(It.IsAny<int>(), It.IsAny<int>()) 
    .Returns<int, int>((a, b) => a < b); 
+0

+1,但是你有一個錯字。你需要在'(a,b)'和'{return a '。 – NightOwl888 2013-11-10 22:02:42

+1

謝謝,看起來像Piotr照顧它感謝。 – Gustyn 2014-03-07 16:41:21

+1

不錯,爲我工作! – willem 2014-07-16 12:28:54

8

對於最簡潔的方法是:

mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>(); 
... 
public string IsLarge() 
{ 
    return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100); 
} 

如果該方法有多個參數,則不能應用該方法。還有可能被使用的「處理方法」,模仿要達到什麼:

/// <summary> 
/// Tests if a moq can send an exception with argument checking 
///</summary> 
[TestMethod] 
public void TestException() 
{ 
    Mock<IMath> mock = new Mock<IMath>(); 
    mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())); 

    mock.Setup(foo => foo.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())) 
     .Callback<int, int>((i, j) => CheckArgs(i, j)); 

    try 
    { 
     mock.Object.AddNumbersBetween(1, 2); 
    } 
    catch (Exception ex) 
    { 
     // Will not enter 
     Console.WriteLine("Exception raised: {0}", ex); 
    } 
    try 
    { 
     mock.Object.AddNumbersBetween(2, 1); 
    } 
    catch (Exception ex) 
    { 
     // Will enter here, exception raised 
     Console.WriteLine("Exception raised: {0}", ex); 
    } 
} 

private bool CheckArgs(int i, int j) 
{ 
    if(i > j) 
     throw new ArgumentException(); 
    return true; 
} 
+0

這隻適用於單個參數而不適用於多個參數 – 2010-11-02 20:48:51

+0

我的不好......還有另外一種處理方法,如果參數沒有通過驗證,回調會拋出異常。 我用這種方法編輯了我的答案 – srodriguez 2010-11-03 08:58:10