2012-04-24 50 views
3

我有以下的库:如何使用模拟匿名类型的设置?

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} 

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

回答

3

可以使用自定义的匹配有一点反思的帮助:

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"); 
     }); 
}  
+0

太谢谢你了。 – 2012-05-01 08:06:54

1

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

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