我是Moq的新手,并且看起来似乎是个愚蠢的问题。 如果我根据循环执行设置它将无法匹配,但如果我手动进行“identicatal”设置,我会得到一个匹配。
我正在使用NuGet的Moq 4.0.10827
我的界面被嘲笑很简单:
public interface IMyInterface
{
string GetValue(string input);
}
整个测试程序如下。 两种方法的预期输出相同,但版本2()
不打印“Foo”代码:
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
---------
编辑:程序输出
答案 0 :(得分:2)
这是一种更通用的方式,单独使用此设置可以让您返回从参数中获得的内容。
mock.Setup(item => item.GetValue(It.IsAny<string>())).Returns((string input) => input);
通过使用It.Is<string>(s => s == "Bar")
,您可能会覆盖第一个谓词。尝试更改顺序或字符串,并检查它的行为方式。
如果你想分别检查价值,你可以做这样的事情
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);
}
答案 1 :(得分: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。