简体   繁体   English

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

[英]Comparing lists of objects with double property with FluentAssertions (C#)

I am trying to compare two list of objects with FluentAssertions. 我试图用FluentAssertions比较两个对象列表。 The objects have a property stored as a double that may be off by a small amount. 这些对象的属性存储为可能会少量偏离的双精度型。 Is there an efficient way to do this without iterating through the lists? 有没有一种有效的方法可以执行此操作而无需遍历列表? My current method looks like 我目前的方法看起来像

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

Which is a little ugly and irritating as this issue keeps on coming up. 随着这个问题的不断出现,这有点丑陋和令人不快。 Another possibility (inspired by Fluent Assertions: Compare two numeric collections approximately ) is 另一种可能性(受Fluent Assertions的启发:大约比较两个数字集合 )是

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

Where I would write the AreEqualApproximately function myself. 我自己写AreEqualApproximately函数的位置。 If possible, I would like to do the comparison without defining my own helper methods or iterating through the lists by index. 如果可能的话,我想做比较而不定义自己的辅助方法或按索引遍历列表。

The following should also work using the options available in ShouldAllBeEquivalentTo 以下内容也应使用ShouldAllBeEquivalentTo可用的选项进行ShouldAllBeEquivalentTo

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

You can create extension methods that will merge your actual and expected values into a single list and foreach over them: 您可以创建扩展方法,这些方法会将您的实际值和期望值合并到一个列表中,并在它们之间进行遍历:

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

Then, you can use it like this: 然后,您可以像这样使用它:

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

Based on Fluent Assertions: Approximately compare a classes properties 基于流利的断言:近似比较类的属性

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

Turns out to work the best for me, although because I have to do this several times, I ended up changing the options for FluentAssertions globally in TestInitialize . 原来的工作最适合我,但因为我不得不这样做几次,我最终改变了在全球范围内FluentAssertions选项TestInitialize

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM