使用 FluentAssertions (C#) 比较具有双 属性 的对象列表
Comparing lists of objects with double property with FluentAssertions (C#)
我正在尝试将两个对象列表与 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);
}
随着这个问题不断出现,这有点丑陋和恼人。另一种可能性(受 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
函数的地方。如果可能的话,我想在不定义自己的辅助方法或按索引遍历列表的情况下进行比较。
您可以创建扩展方法,将您的实际值和预期值合并到一个列表中,并对其进行 foreach:
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));
使用 ShouldAllBeEquivalentTo
中可用的选项,以下内容也应该有效
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>()
结果证明对我来说效果最好,尽管因为我必须多次这样做,所以我最终在 TestInitialize
.
中全局更改了 FluentAssertions 的选项
我正在尝试将两个对象列表与 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);
}
随着这个问题不断出现,这有点丑陋和恼人。另一种可能性(受 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
函数的地方。如果可能的话,我想在不定义自己的辅助方法或按索引遍历列表的情况下进行比较。
您可以创建扩展方法,将您的实际值和预期值合并到一个列表中,并对其进行 foreach:
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));
使用 ShouldAllBeEquivalentTo
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>()
结果证明对我来说效果最好,尽管因为我必须多次这样做,所以我最终在 TestInitialize
.