2011-11-24 74 views
2

我是Moq新手,並且似乎有一個愚蠢的問題。 如果我執行基於循環的設置,它將不匹配,但如果我手動執行「ide​​nticatal」設置,我確實會得到一個匹配。Moq不匹配(簡單)設置​​

我使用起訂量4.0.10827,從的NuGet

我的界面處嘲笑很簡單:

public interface IMyInterface 
{ 
    string GetValue(string input); 
} 

測試,整個程序如下。 預期的輸出是這兩種方法是相同的,但「富」不打印的版本2()

代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Version1(); 
     Console.WriteLine("---------"); 
     Version2(); 
     Console.WriteLine("---------"); 
     Console.ReadKey(); 
    } 

    private static void Version1() 
    { 
     var mock = new Mock<IMyInterface>(); 

     mock.Setup(x => x.GetValue(It.Is<string>(s => s == "Foo"))).Returns("Foo"); 
     mock.Setup(x => x.GetValue(It.Is<string>(s => s == "Bar"))).Returns("Bar"); 

     IMyInterface obj = mock.Object; 

     Console.WriteLine(obj.GetValue("Foo")); 
     Console.WriteLine(obj.GetValue("Bar")); 
    } 

    private static void Version2() 
    { 
     var mock = new Mock<IMyInterface>(); 

     string[] keys = new string[] { "Foo", "Bar" }; 

     foreach (string key in keys) 
     { 
      mock.Setup(x => x.GetValue(It.Is<string>(s => s == key))).Returns(key); 
     } 

     IMyInterface obj = mock.Object; 

     Console.WriteLine(obj.GetValue("Foo")); // Does not match anything 
     Console.WriteLine(obj.GetValue("Bar"));    
    } 
} 

我把它我失去了一些東西..但什麼?

程序輸出:

Foo 
Bar 
--------- 

Bar 
--------- 

編輯:輸出從程序

回答

2

這裏有一個更通用的方法,僅此安裝程序將讓你回到你從參數得到什麼。

mock.Setup(item => item.GetValue(It.IsAny<string>())).Returns((string input) => input); 

通過使用It.Is<string>(s => s == "Bar")您可能會覆蓋第一個謂詞。嘗試改變順序或字符串,並檢查它的行爲。

如果你想seperetely校驗值,你可以做這樣的事情

mock.Setup(item => item.GetValue("Foo")).Returns("Foo"); 
mock.Setup(item => item.GetValue("Bar")).Returns("Bar"); 

在一個循環:

foreach (string key in keys) 
{ 
    mock.Setup(x => x.GetValue(key)).Returns(key); 
} 
+0

謝謝。這篇文章對我試圖實現的某種程度的簡化。我將其降低到了可以再現行爲的最簡單的情況。實際上,我有一個基於輸入返回對象的服務,因此一般的「返回標識」是不夠的:/ – Thomas

+0

檢查我的更新。這是你想要做什麼? –

+0

是的,這只是上次迭代中似乎存在的項目。不是你在第一版中做了什麼?在任何一種情況下,我都不明白爲什麼第二個不起作用。 – Thomas

0

@Ufuk是正確的。澄清,這與Moq無關。這是經典的「訪問修改關閉」問題(這是警告消息ReSharper給出的)。

例如:

void Main() 
{ 
    var actions = new List<Func<string, bool>>(); 

    string[] keys = new string[] { "Foo", "Bar" }; 

    foreach (string key in keys) 
    { 
     actions.Add(s => s == key); 
    } 

    foreach (var action in actions) 
    { 
     Console.WriteLine("Is Foo: " + action("Foo")); 
     Console.WriteLine("Is Bar: " + action("Bar")); 
     Console.WriteLine(); 
    } 
} 

結果:

Is Foo: False 
Is Bar: True 

Is Foo: False 
Is Bar: True

Jon Skeet's answer to C# Captured Variable In Loop和Eric Lippert的Closing over the loop variable considered harmful