2014-03-27 64 views
0

我有一个类的函数返回一个基于类属性的状态值。在这个例子中,如果Name不为null,我希望HasName()返回true。我可以简单地做Returns(false),但是我希望它评估为lambda,以便在测试过程中修改Name的情况下它可以正常工作。Moq的参考成员lambda

public interface IThing 
{ 
    string Name { get; set; } 
    bool HasName(); 
} 

var mocks = new Dictionary<string, IThing>(); 
Mock<IThing> mockThing; 

mockThing = new Mock<IThing>(); 
mockThing.SetupProperty(m => m.Name, "test"); 
mockThing.Setup(m => m.HasName()).Returns(() => 
    { 
     return mockThing.Object.Name != null; 
    }); 
mocks["first"] = mockThing.Object; 

mockThing = new Mock<IThing>(); 
mockThing.SetupProperty(m => m.Name, "test"); 
mockThing.Setup(m => m.HasName()).Returns(() => 
    { 
     return mockThing.Object.Name != null; 
    }); 
mocks["second"] = mockThing.Object; 


Console.WriteLine(mocks["first"].HasName()); 
mocks["first"].Name = null; 
Console.WriteLine(mocks["first"].HasName()); 

第二个Console.WriteLine由于作用域(引用第二个模拟)而打印true而不是false。实际上,Resharper抱怨“访问修改后的关闭”。什么是正确的方法来做到这一点?

回答

1

虽然你的设计有点怪,但你可以在你的Setup功能访问与mockThing.Object生成的模拟对象:

mockThing.Setup(m => m.HasName()).Returns(() => 
{ 
    return mockThing.Object.Name != null; 
}); 

var thing = mockThing.Object; 
var hasName = thing.HasName(); // true because Name returns "test" 
thing.Name = null; 
hasName = thing.HasName(); // false 

的问题是,你引用的mockThing与lambda表达式,然后你reasigning它。所以这两个安装程序将最终使用相同的实例。

从字典中使用嘲笑,也将努力:

var mocks = new Dictionary<string, IThing>(); 
Mock<IThing> mockThing; 

mockThing = new Mock<IThing>(); 
mocks["first"] = mockThing.Object; 
mockThing.SetupProperty(m => m.Name, "test"); 
mockThing.Setup(m => m.HasName()).Returns(() => 
{ 
    return mocks["first"].Name != null; 
}); 


mockThing = new Mock<IThing>(); 
mocks["second"] = mockThing.Object; 
mockThing.SetupProperty(m => m.Name, "test"); 
mockThing.Setup(m => m.HasName()).Returns(() => 
{ 
    return mocks["second"].Name != null; 
}); 


Console.WriteLine(mocks["first"].HasName()); 
mocks["first"].Name = null; 
Console.WriteLine(mocks["first"].HasName()); 
+0

这并不在我有限的例子的工作,但我意识到,我的问题更多的是与作用域。我添加了多个mock,lambda中的范围是一个问题。我通过更好的演示更新了我的示例。 – wtjones

+0

我已经更新了我的答案 – nemesv

+0

这对我很有用。我还能够在foreach循环中创建模拟,只要我在每次迭代时将密钥分配给新的变量。 谢谢! – wtjones