使用Moq在C#中设置索引器
我无法弄清楚如何使用Moq在C#中设置索引器 。 Moq文档很薄弱,我已经做了很多搜索……我想做的事情在如何设置索引属性的解决方案中类似:
var someClass = new Mock(); 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(); someClass.Setup(o => o.SomeIndexedProperty[It.IsAny()]) .Returns(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]);
我找到了解决问题的方法。 它需要改变我的想法…我一直在寻找使用NUnit的Assert
来validation我的someClass
模拟中的索引器设置器是否被正确的值调用。
似乎使用Moq支持的方法是使用VerifySet
函数。 一个人为的例子:
someClass.Object.SomeIndexedProperty[3] = 25; someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);
unit testing通过,因为SomeIndexedProperty[3]
设置为25,否则将失败。
使用Moq 3.1.416.3
安装程序不适用于索引器(因为它需要一个表达式,这意味着赋值语句被排除在外)
所以你需要像使用SetupSet一样
_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny()) .Callback( (key, value) => persistedValue = value);
一个小警告:如果键是“MruNotes”,则此表达式仅匹配。 我无法使用像It.IsAny这样的匹配器。
在您的测试中,您对索引器的getter的唯一设置期望 – 这将始终返回您的数组中的相应值。 索引器的行为不像真实的东西。 您可以尝试一些方法来修复它:
-
您可以检查是否可以存根此索引器。 我个人使用RhinoMocks,所以我不知道是否实现了这一点
someClass.SetupProperty(f => f.SomeIndexedProperty);
-
您也可以尝试模拟setter并使其更改底层数组。 我的第一个猜测就是沿着这些方向尝试一些东西(不保证它会起作用):
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny
()] = It.IsAny ()) .Callback((index, value) => someValues[index] = value); -
或者,如果ISomeClass接口足够小,您可以自己创建一个存根实现(将索引器实现为字典,数组等)