我有以下存储库:
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}
这样我就可以设定使用正确的匿名类型的期望。
答案 0 :(得分: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");
});
}
答案 1 :(得分: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);
});
}