20

我无法弄清楚如何使用 Moq 在 C#中设置索引器。起订量文档很薄弱,我已经做了很多搜索......我想做的与如何起订量设置索引属性的解决方案类似:

var someClass = new Mock<ISomeClass>();
someClass.SetupSet(o => o.SomeIndexedProperty[3] = 25);

我想修改上面的内容以适用于任何索引和任何值,所以我可以做这样的事情:

someClass.Object.SomeIndexedProperty[1] = 5;

目前我有以下内容,这对于索引属性获取器非常有用,但是如果我设置了值 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]);
4

3 回答 3

12

我找到了解决我的问题的方法。这需要改变我的想法......我一直在寻找使用 NUnitAssert来验证我的someClass模拟中的索引器设置器是否以正确的值被调用。

似乎使用 Moq 支持的方法是使用该VerifySet功能。一个人为的例子:

someClass.Object.SomeIndexedProperty[3] = 25;
someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);

单元测试通过,因为SomeIndexedProperty[3]设置为 25,否则会失败。

于 2010-05-27T13:51:51.273 回答
6

使用最小起订量 3.1.416.3

设置不适用于索引器(因为它需要一个表达式,这意味着排除了赋值语句)

所以你需要像这样使用 SetupSet

_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>())
                .Callback<string,string>( (key, value) => persistedValue = value);

一个小警告:这个表达式只有在键是“MruNotes”时才匹配。我无法使用像 It.IsAny 这样的匹配器作为密钥。

于 2010-11-27T18:47:38.213 回答
3

在您的测试中,您对索引器的获取器唯一设定的期望 - 这将始终从您的数组中返回相应的值。索引器的行为不像真实的东西。您可以尝试一些方法来修复它:

  1. 您可以检查是否可以存根此索引器。我个人使用的是 RhinoMocks,所以我不知道这是否实现

    someClass.SetupProperty(f => f.SomeIndexedProperty);
    
  2. 您也可以尝试模拟 setter 并使其更改底层数组。我的第一个猜测是尝试这些方面的东西(不保证它会起作用):

    someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>())
    .Callback((index, value) => someValues[index] = value);
    
  3. 或者,如果 ISomeClass 接口足够小,您可以自己创建一个存根实现(将索引器实现为字典、数组等)

 

于 2010-05-27T13:49:28.440 回答