我无法弄清楚如何使用Moq在C#中设置indexers。 Moq文档很薄弱,我已经做了很多搜索......我想做的事情与How to Moq Setting an Indexed property的解决方案类似:
var someClass = new Mock<ISomeClass>();
someClass.SetupSet(o => o.SomeIndexedProperty[3] = 25);
我想修改上面的内容以适用于任何索引和任何值,所以我可以这样做:
someClass.Object.SomeIndexedProperty[1] = 5;
目前我有以下内容,它对索引属性getter非常有用,但是如果我设置了值,Moq会忽略它:
var someValues = new int[] { 10, 20, 30, 40 };
var someClass = new Mock<ISomeClass>();
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()])
.Returns<int>(index => someValues[index]);
// Moq doesn't set the value below, so the Assert fails!
someClass.Object.SomeIndexedProperty[3] = 25;
Assert.AreEqual(25, someClass.Object.SomeIndexedProperty[3]);
答案 0 :(得分:11)
我找到了解决问题的方法。它需要改变我的想法...我一直在寻找使用NUnit的Assert
来验证我的someClass
模拟中的索引器设置器是否被调用了正确的值。
似乎使用Moq支持的方法是使用VerifySet
函数。一个人为的例子:
someClass.Object.SomeIndexedProperty[3] = 25;
someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);
自SomeIndexedProperty[3]
设置为25以来单位测试通过,否则将失败。
答案 1 :(得分:5)
使用Moq 3.1.416.3
安装程序不适用于索引器(因为它需要一个表达式,这意味着赋值语句被排除)
所以你需要使用像
这样的SetupSet_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>())
.Callback<string,string>( (key, value) => persistedValue = value);
一个小警告: 如果键是“MruNotes”,则此表达式仅匹配。我无法使用像It.IsAny这样的匹配器作为密钥。
答案 2 :(得分:3)
在您的测试中,您对索引器的getter的唯一设置期望 - 这将始终返回您的数组中的相应值。索引器的行为不像真实的东西。您可以尝试一些方法来修复它:
您可以检查是否可以存根此索引器。我个人使用RhinoMocks,所以我不知道是否实现了这个
someClass.SetupProperty(f => f.SomeIndexedProperty);
您也可以尝试模拟setter并使其更改底层数组。我的第一个猜测是尝试这些方面的东西(不保证它会起作用):
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>())
.Callback((index, value) => someValues[index] = value);
或者,如果ISomeClass接口足够小,您可以自己创建一个存根实现(将索引器实现为字典,数组等)。