使用FluentAssertions(C#)比较具有double属性的对象列表

时间:2017-07-21 16:35:44

标签: c# list unit-testing precision fluent-assertions

我试图用FluentAssertions比较两个对象列表。对象具有存储为double的属性,可以少量关闭。有没有一种有效的方法可以在不迭代列表的情况下执行此操作?我当前的方法看起来像

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

随着这个问题不断出现,这有点难看和恼人。另一种可能性(受Fluent Assertions: Compare two numeric collections approximately启发)是

actualList.Select(o => o.DoubleProperty)
          .Should().Equal(expectedList.Select(o => o.DoubleProperty),
                          (left, right) => AreEqualApproximately(left, right, precision));

我自己写AreEqualApproximately函数的地方。如果可能的话,我想在不定义自己的帮助器方法或通过索引迭代列表的情况下进行比较。

3 个答案:

答案 0 :(得分:2)

以下内容也可以使用ShouldAllBeEquivalentTo

中提供的选项
actualList.ShouldAllBeEquivalentTo(expectedList, options => options
    .Using<double>(ctx => ctx.Subject.Should()
                             .BeApproximately(ctx.Expectation, precision))
    .When(o => o.SelectedMemberPath == "DoubleProperty"));

答案 1 :(得分:1)

您可以创建扩展方法,将您的实际值和期望值合并到一个列表中并覆盖它们:

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

然后,您可以像这样使用它:

actualList.Merge(expectedList)
   .ForEach(i => 
   i.Item1.DoubleProperty
   .Should().BeApproximately(i.Item2.DoubleProperty, precision)); 

答案 2 :(得分:1)

基于Fluent Assertions: Approximately compare a classes properties

actualList.ShouldAllBeEquivalentTo(
    expectedList,
    options => options.Using<double>(d => d.Subject.Should().BeApproximately(d.Expectation, precision))
                      .WhenTypeIs<double>()

事实证明,对我来说最好,但因为我必须多次这样做,所以我最终在TestInitialize全局更改了FluentAssertions的选项。