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

发布于 2024-09-02 22:34:49 字数 976 浏览 10 评论 0原文

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

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]);

I'm having trouble figuring out how to set indexers in C# with Moq. The Moq documentation is weak, and I've done a lot of searching... what I'd like to do is similar in the solution to How to Moq Setting an Indexed property:

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

I want to modify the above to work for any index and any value so I can just do something like this:

someClass.Object.SomeIndexedProperty[1] = 5;

Currently I have the following, which works great for the indexed property getter, but if I ever set the value Moq ignores it:

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]);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情空心 2024-09-09 22:34:49

我找到了解决问题的方法。这需要我的思维转变...我一直在寻找使用 NUnit 的 Assert 来验证我的 someClass 模拟中的索引器设置器是否使用正确的值进行调用。

看来 Moq 支持的方法是使用 VerifySet 函数。一个人为的示例:

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

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

I found a solution to my problem. It requires a shift in my thinking... I had been looking to use NUnit's Assert to verify that the indexer setter in my someClass mock was being called with the correct value.

It seems that with Moq the supported way to do this is to use the VerifySet function. A contrived example:

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

The unit test passes since SomeIndexedProperty[3] is set to 25, but would fail otherwise.

天涯离梦残月幽梦 2024-09-09 22:34:49

使用 Moq 3.1.416.3

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

因此您需要像使用 SetupSet 一样使用

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

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

Using Moq 3.1.416.3

Setup won't work for indexers (because it takes an expression which means assignment statements are ruled out)

so you need to use SetupSet like

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

A small caveat:
this expression only matches if the key is "MruNotes". I was not able to use a matcher like It.IsAny for the key.

残花月 2024-09-09 22:34:49

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

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

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

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

 

In your test your only set expectations for the getter of the indexer - and this will always return the corresponding value from your array. The indexer doesn't behave like a real thing. You can try a few things to have it fixed:

  1. You can check if you can stub this indexer. I am personally using RhinoMocks, so I have no idea if this is implemented

    someClass.SetupProperty(f => f.SomeIndexedProperty);
    
  2. You can try to mock the setter as well and make it to change the underlying array. My first guess would be to try something along these lines (no guarantee it will work):

    someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>())
    .Callback((index, value) => someValues[index] = value);
    
  3. Or if the ISomeClass interface is small enough, you could just created a stub implementation yourself (that would have the indexer implemented as a dictionary, array etc.)

 

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文