3
这里是我遇到问题的简化版本:安装在模拟没有返回预期值
public interface IService
{
IProvider Provider { get; }
}
public interface IProvider
{
List<int> Numbers{ get; }
string Text { get; }
}
[TestMethod]
public void ServiceTest()
{
var service = new Mock<IService>();
var provider = new Mock<IProvider>();
service.Setup(s => s.Provider).Returns(provider.Object); // A
service.Setup(s => s.Provider.Text).Returns("some text"); // B - incorrect
// they actually meant to do this, instead of 'B'
// provider.Setup(p => p.Text).Returns("some text");
provider.Setup(p => p.Numbers).Returns(new List<int> { 1, 2, 3 });
DummyApplicationCode(service.Object);
}
int DummyApplicationCode(IService service)
{
// will throw, because the Provider was replaced at 'B'
int shouldBeOne = service.Provider.Numbers.First();
return shouldBeOne;
}
一个单元测试失败,因为这样在测试中的应用程序代码下来,嘲笑IService
返航错IProvider
。
我最终找到行(记住我一直在寻找的代码是不是如上一样简单),这造成了它,标记为上面的“B”,其别人都因误会起订量设置添加。
我知道后面的模拟设置将覆盖以前的设置但我没有发现这个问题,因为违规行的返回是针对单独的子属性。
我期望这是通过设计,但它扔了我,因为我没有预料到有人会这样做。
我的问题:因为在“B”的设置是只关注供应商文本,为什么服务“提供者”属性需要更换这是在“A”定义的回报?
'如果为相同的方法或属性指定了多个设置,则最新的设置获胜并且将执行该设置。 'Provider'是你的情况下正在执行的表达式树的一部分。因此,涉及该路径的任何以前的设置也将被覆盖。 – Nkosi
@Nkosi这是公平的,谢谢,但我的查询是为什么它真的需要**来做到这一点,而不是将文本返回到现有的提供者模拟。就我个人而言,我希望看到该行被标记为错误。 – mungflesh
我明白你的观点。我的猜测是每个'安装程序'都被孤立地处理。一个独特的动作/函数被调用。你可以在GitHub上为它创建一个功能请求的问题。 – Nkosi