【问题标题】:Using Moq to set any by any key and value使用 Moq 通过任何键和值设置任何
【发布时间】:2011-09-11 18:16:41
【问题描述】:

在问题的最后: Using Moq to set indexers in C#,有人强调了我也遇到的问题。但他们没有找到解决办法。

具体来说,我正在尝试使用通用It.IsAny<string> 作为键的匹配器并通过It.IsAny<object> 设置值。通过索引访问并设置值时,它永远不会匹配,也不会访问我的回调方法。所以我的单元测试失败了。

var stateTable = new HashTable;
var httpSession = new Mock<HttpSessionStateBase>();

//works via httpSession.Add(key, value);
httpSession.Setup(x => x.Add(It.IsAny<string>(), It.IsAny<object>()))
    .Callback((string index, object value) => {
        var i = index;
        var v = value;

            stateData[i] = v;
    });

//does not work via httpSession[key] = value;
httpSession.SetupSet(x => x[It.IsAny<string>()] = It.IsAny<object>())
    .Callback( (string index, object value) => {
        var i = index;
        var v = value;

        stateData[i] = v;
});

我正在使用最小起订量 4.0.10827

【问题讨论】:

  • 我认为您应该在这个问题中说明问题所在,以使其更清楚。以目前的形式,很难推断出问题所在。
  • 他的问题是,当您使用“It.IsAny”作为索引器内部的值时,它永远不会匹配。
  • 没错,并编辑帖子以使其更清晰。

标签: c# unit-testing moq indexer


【解决方案1】:

根据我的经验,这永远不会奏效,您不能将 It.IsAny 用作索引器表达式中的匹配器。但是,如果您在索引器中输入具体值,它将匹配。 例如,以下确实有效:

httpSession.SetupSet(x => x["someValue"] = It.IsAny<object>())
    .Callback( (string index, object value) => {
        var i = index;
        var v = value;

        stateData[i] = v;
});

【讨论】:

  • 我看过一些代码,来自喜欢 Rhino.Mocks 的人,他们能够做到这一点。我希望这不是起订量不足的原因。
  • 我不知道 RhinoMocks,但至少在起订量方面,这似乎是一种不足
  • 我今天早上在 Moq 邮件列表中发布了对这篇文章的引用和一个示例测试用例。 @kzu 看过这篇文章,听起来大家都同意这个错误信息和相应的误导性错误信息都需要修复。
  • 这个问题实际上已经知道了一段时间,但不幸的是,我可以确认问题仍然存在。更多细节在这里:github.com/Moq/moq4/issues/218.
【解决方案2】:

这是我为验证读取所做的。

_httpSessionStateBaseMock.VerifySet(x => x["keyname"] = It.IsAny<YourObject>(), Times.Once());

对于我刚刚阅读的内容

_httpSessionStateBaseMock.Verify(x => x["keyname"],Times.Once());

【讨论】:

    【解决方案3】:

    我不喜欢它,但我能够使用新的继承类来解决它。 然后我覆盖索引器并调用一个可以模拟的虚拟方法。

    public class HttpSessionStateBaseProxy : HttpSessionStateBase
    {
        public virtual void SetItem(string key, object value)
        {
            base[key] = value;
        }
        public override object this[string name]
        {
            get
            {
                return base[name];
            }
            set
            {
                SetItem (name, value);
            }
        }
    
    }
    

    模拟是由:

    Mock<HttpSessionStateBaseProxy> Session = new Mock<HttpSessionStateBaseProxy>(MockBehavior.Loose);
    Session.CallBase = true;
    Session.Setup(x => x.SetItem(It.IsAny<string>(),It.IsAny<object>()))
            .Callback<string,object>((string index, object value) =>
            {
                if (!this.SessionItems.Contains(index)) this.SessionItems.Add(index, value);
                else this.SessionItems[index] = value;
    
    
            });
    
            Session.Setup(s => s[It.IsAny<string>()]).Returns<string>(key =>
            {
    
                return this.SessionItems[key];
    
            });
    

    【讨论】:

      猜你喜欢
      • 2017-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多