将具有双重属性的对象列表与FluentAssertions(C#)进行比较

将具有双重属性的对象列表与FluentAssertions(C#)进行比较,c#,list,unit-testing,precision,fluent-assertions,C#,List,Unit Testing,Precision,Fluent Assertions,我试图比较两个具有FluentAssertions的对象列表。对象具有存储为双精度的属性,该属性可能会被少量禁用。有没有一种有效的方法可以在不遍历列表的情况下实现这一点?我当前的方法看起来像 actualList.ShouldAllBeEquivalentTo(expectedList, options => options.Excluding(o => o.DoubleProperty)); for (var i = 0; i < actualList.Count; i++

我试图比较两个具有FluentAssertions的对象列表。对象具有存储为双精度的属性,该属性可能会被少量禁用。有没有一种有效的方法可以在不遍历列表的情况下实现这一点?我当前的方法看起来像

actualList.ShouldAllBeEquivalentTo(expectedList, options => options.Excluding(o => o.DoubleProperty));

for (var i = 0; i < actualList.Count; i++)
{
    actualList[i].DoubleProperty
                 .Should().BeApproximately(expectedList[i].DoubleProperty, precision);
}

我将自己编写的
函数大致相当于
函数。如果可能,我希望在不定义自己的帮助器方法或按索引遍历列表的情况下进行比较。

您可以创建扩展方法,将实际值和预期值合并到单个列表中,并对其进行遍历:

public static class ExtensionMethods
{
    public static IEnumerable<ValueTuple<T, T>> Merge<T>(this List<T> a, List<T> b)
    {
        for (int x = 0, y = 0; x < a.Count && y < a.Count; x++, y++) 
        {
            yield return ValueTuple.Create(a[x], b[y]);
        }
    }

    public static void ForEach<T>(this IEnumerable<T> s, Action<T> m)
    {
       foreach (var i in s) m(i);
    }
}

使用
shouldlbeequivalento

actualList.ShouldAllBeEquivalentTo(expectedList, options => options
    .Using<double>(ctx => ctx.Subject.Should()
                             .BeApproximately(ctx.Expectation, precision))
    .When(o => o.SelectedMemberPath == "DoubleProperty"));
actualList.shoulldAllbeeEquivalentTo(expectedList,options=>options
.Using(ctx=>ctx.Subject.Should()
.BEA近似值(ctx.期望值、精度))
.When(o=>o.SelectedMemberPath==“DoubleProperty”);
基于

actualist.allbeequivalentto(
预期名单,
options=>options.Using(d=>d.Subject.Should().beapproximaty(d.Expectation,precision))
.WhenTypeIs()

结果证明对我来说效果最好,尽管因为我不得不这样做几次,我最终在
TestInitialize

中全局更改了FluentAssertions的选项,这有什么不好呢?我的意思是,除了没有新行序列来分解点链之外?@hoodaticus在C#中,我真的不应该重复列表代码中的index.Beauty是您真正需要感知的东西。您需要将源数据转换为ValueTuple列表,其中第一项是actualList成员,第二项是相应的expectedList成员。然后您就可以执行list.ForEach(i=>i.Item1.DoubleProperty.Should().beapproximaty(i.Item2.DoubleProperty,precision));当前形式的代码需要按索引进行循环的原因是,它必须手动关联两个单独的列表。将它们放在同一个列表中,您就很好了。如果您这样回答,我将接受它。请看这个
actualList.Merge(expectedList)
   .ForEach(i => 
   i.Item1.DoubleProperty
   .Should().BeApproximately(i.Item2.DoubleProperty, precision)); 
actualList.ShouldAllBeEquivalentTo(expectedList, options => options
    .Using<double>(ctx => ctx.Subject.Should()
                             .BeApproximately(ctx.Expectation, precision))
    .When(o => o.SelectedMemberPath == "DoubleProperty"));
actualList.ShouldAllBeEquivalentTo(
    expectedList,
    options => options.Using<double>(d => d.Subject.Should().BeApproximately(d.Expectation, precision))
                      .WhenTypeIs<double>()