C# 使用Moq在C中设置索引器#

C# 使用Moq在C中设置索引器#,c#,unit-testing,moq,indexer,C#,Unit Testing,Moq,Indexer,我很难弄清楚如何在最小起订量的情况下进入C#。Moq文档很弱,我做了很多搜索。。。我想做的与解决方案类似: 目前,我有以下内容,这对于索引属性getter非常有用,但如果我设置值Moq,就会忽略它: var someValues = new int[] { 10, 20, 30, 40 }; var someClass = new Mock<ISomeClass>(); someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<

我很难弄清楚如何在最小起订量的情况下进入C#。Moq文档很弱,我做了很多搜索。。。我想做的与解决方案类似:

目前,我有以下内容,这对于索引属性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]);
var someValues=newint[]{10,20,30,40};
var someClass=newmock();
Setup(o=>o.SomeIndexedProperty[It.IsAny())
.Returns(index=>someValues[index]);
//Moq没有设置下面的值,因此断言失败!
someClass.Object.SomeIndexedProperty[3]=25;
AreEqual(25,someClass.Object.SomeIndexedProperty[3]);

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

  • 您可以检查是否可以存根此索引器。我个人正在使用Rhinomock,所以我不知道这是否已经实现

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

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


  • 我找到了解决问题的办法。这需要我改变思维。。。我一直在寻找使用NUnit的
    Assert
    来验证我的
    someClass
    mock中的索引设置器是否用正确的值调用

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

    someClass.Object.SomeIndexedProperty[3] = 25;
    someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);
    
    单元测试通过,因为
    SomeIndexedProperty[3]
    设置为25,否则将失败。

    使用Moq 3.1.416.3

    安装程序对索引器不起作用(因为它采用了一个表示排除赋值语句的表达式)

    所以你需要像这样使用SetupSet

    _settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>())
                    .Callback<string,string>( (key, value) => persistedValue = value);
    
    \u setingsstore.SetupSet(store=>store[“MruNotes”]=It.IsAny())
    .Callback((键,值)=>persistedValue=value);
    
    一个小警告:
    此表达式仅在键为“MruNotes”时匹配。我无法使用像它这样的匹配器。IsAny用于键。

    索引变量是什么?它是从哪里来的?我是新来的莫克,所以也许我做错了什么。。。但是我认为Returns lambda中的index参数是由Setup lambda中的It.IsAny()表达式提供的。我也不是专家(我使用的是Rhinomock)。someClass.Object.SomeIndexedProperty[3]是否返回40?是的,这是观察到的行为。#1在我的实验中不起作用。我试图做一些类似于#2的事情,但我没有尝试回调。还要感谢你指出#3——有时你会试图敲入一个螺钉,而不是仅仅找到一把螺丝刀。我也有同样的问题,只是我的索引属性是只读的,即它只有一个
    get
    访问器。你知道我该怎么嘲笑这个吗?
    someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>())
    .Callback((index, value) => someValues[index] = value);
    
    someClass.Object.SomeIndexedProperty[3] = 25;
    someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);
    
    _settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>())
                    .Callback<string,string>( (key, value) => persistedValue = value);