我正在创建单元测试,我将在其中比较对象列表与另一个。
目前我正在使用Fluent断言与specflow和nunit的组合。我已经使用Fluent断言进行了如下比较:
public void TestShizzle()
{
// I normally retrieve these lists from a moq database or a specflow table
var expected = list<myObject>
{
new myObject
{
A = 1,
B = "abc"
}
}
var found = list<myObject>
{
new myObject
{
A = 1,
B = "def"
}
}
// this comparison only compares a few columns. The comparison is also object dependent. I would like to make this dynamic
found.Should().BeEquivalentTo(
expected,
options =>
options.Including(x => x.A));
}
我真正想要的是能够使用泛型而不是指定类型。我还想决定在编译时比较哪些属性。这是因为数据库中有大量的表。我想我需要使用Linq表达式,但我不知道如何去做。函数应该看起来像这样:
public void GenericShizzle<T>(List<T> expected, List<T> found, IEnumerable<PropertyInfo> properties)
{
Expression<Func<T, object>> principal;
foreach(var property in properties)
{
// create the expression for including fields
}
found.Should().BeEquivalentTo(
expected,
options =>
// here is need to apply the expression.
}
我真的不知道如何得到工作的正确表达,或者这是否是最好的方法。我认为我需要创建一个属性表达式,是由包含函数理解,但也许一个不同的方法可以使用?
有Including
方法过载接受Expression<Func<IMemberInfo, bool>>
,可用于根据成员的信息动态过滤成员:
IEnumerable<PropertyInfo> properties = ...;
var names = properties
.Select(info => info.Name)
.ToHashSet();
found.Should()
.BeEquivalentTo(expected,
options => options.Including((IMemberInfo mi) => names.Contains(mi.Name))); // or just .Including(mi => names.Contains(mi.Name))