【问题标题】:How to use setup of a mocked anonymous type?如何使用模拟匿名类型的设置?
【发布时间】:2012-04-24 14:06:06
【问题描述】:

我有以下存储库:

interface IReportingRepository where T: Report
{
     IEnumerable<T> GetReports<T>(object constraints);
}

我正在尝试模拟对这个存储库的调用:

var reportingRepostory = new Mock<IReportingRepository>();
                       reportingRepostory.Setup(x => 
                       x.GetReports<ServiceReport (Moq.It.IsAny<object>())).
                       Returns(new List<ServiceReport>(){Report1, Report2});

但是不是传入

Moq.It.IsAny<object>()

我要传递匿名类型

new {Activated = true, Enabled = true}

这样我就可以设置我的期望,即使用正确的匿名类型。

【问题讨论】:

    标签: c# moq


    【解决方案1】:

    您可以在反射帮助下使用自定义匹配器:

    var reportingRepostory = new Mock<IReportingRepository>();
    reportingRepostory
        .Setup(x => x.GetReports<ServiceReport>(HasProperties()))
        .Returns(new List<ServiceReport>(){Report1, Report2});
    

    其中HasProperties方法实现如下:

    private object HasProperties()
    {
        return Match.Create(
            (object o)  =>
            {
                var properties = o.GetType().GetProperties();
                return properties.Any(p => p.Name == "Available")
                    && properties.Any(p => p.Name == "Enabled");
            });
    }    
    

    【讨论】:

      【解决方案2】:

      一些原始解决方案无法解决的实现错误:

      new {Activated = true, Enabled = false}
      new {Activated = true, Enabled = true, Extra = "I'm not meant to be here!"}
      new {Activated = true, Enabled = "true"}
      

      根据您的 IReportingRepository GetReports 方法实现的复杂性,可能值得考虑验证匿名类型的属性值和值类型是否符合预期,并且只存在预期的属性。

      var reportingRepostory = new Mock<IReportingRepository>();
      reportingRepostory
          .Setup(x => x.GetReports<ServiceReport>(IsAnonymousType(new {Activated = true, Enabled = true})))
          .Returns(new List<ServiceReport>(){Report1, Report2});
      

      IsAnonymousType 方法在哪里:

      private static object IsAnonymousType(object expected)
      {
          return Match.Create(
              (object actual) =>
              {
                  if (expected == null)
                  {
                      if (actual == null)
                          return true;
                      else
                          return false;
                  }
                  else if (actual == null)
                      return false;
      
                  var expectedPropertyNames = expected.GetType().GetProperties().Select(x => x.Name);
                  var expectedPropertyValues = expected.GetType().GetProperties().Select(x => x.GetValue(expected, null));
                  var actualPropertyNames = actual.GetType().GetProperties().Select(x => x.Name);
                  var actualPropertyValues = actual.GetType().GetProperties().Select(x => x.GetValue(actual, null));
      
                  return expectedPropertyNames.SequenceEqual(actualPropertyNames)
                      && expectedPropertyValues.SequenceEqual(actualPropertyValues);
              });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多