2011-11-24 11 views
2

私はMoqを初めて使い、愚かな問題であると思われるものを持っています。 ループに基づいてセットアップを実行すると、一致しませんが、 "identicatal"設定を手作業で行うと一致します。私は私のインタフェースが嘲笑されているNuGetMoq not matching(simple)setup

から、部品番号4.0.10827を使用しています

は単純です:

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

テスト全体のプログラムは以下の通りです。 予想される出力は、両方の方法で同じですが、「fooが」(バージョン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

ありがとうございます。この投稿は、私が達成しようとしていることのやや単純化されています。私はそれを私がその行動を再現できるような単純なケースに減らしました。実際には、入力に基づいてオブジェクトを返すサービスがあるため、一般的な「返品ID」では不十分です。/ – Thomas

+0

更新を確認してください。それはあなたがやろうとしていることですか? –

+0

ええ、それは存在すると思われる最後の反復からの唯一のアイテムです。私がVersion1でやったことをあなたが示唆したことはありませんか?いずれの場合でも、私はなぜ2番目のdoesntの仕事を理解していない。 – 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とエリックリペットのClosing over the loop variable considered harmfulを参照してください。