比较具有不同项目类型的集合
Posted
技术标签:
【中文标题】比较具有不同项目类型的集合【英文标题】:Comparing collections with different item types 【发布时间】:2015-02-02 18:26:54 【问题描述】:我有两个不同项目类型的集合,例如:
var collection1 = new List<Type1>();
var collection2 = new List<Type2>();
是否可以使用我自己的相等比较器和 FluentAssertions 断言具有不同项目类型的两个集合包含以任何顺序的相等项目?
来自the official FA documentation 的最相关示例认为两个集合是同一类型:
persistedCustomers.Should().Equal(customers, (c1, c2) => c1.Name == c2.Name);
在我的情况下使用这种方法的一个可能的解决方案是基于来自collection2
的项目创建一个新的List<Type1>
集合,并在上面的示例中使用它而不是customers
。
但有时这是不可能的,实际上闻起来像开销。
我想知道是否有一种类似的方法可以像上面那样使用 FA 优雅但适用于具有不同项目类型的集合?
UPDATE 1(尝试使用@DennisDoomen 的建议):
让我们举个更具体的例子。
假设我们有一个 List<DateTime>
的期望值,代表一个月的日期:
var expectation = new List<DateTime>();
一个测试方法返回一个List<int>
的天数:
var actual = new List<int>();
我们要断言测试方法返回的天数集合与期望列表的 DateTime.Day 值组成的集合相同,即:
Assert.AreEqual(expectation[0].Day, actual[0]);
Assert.AreEqual(expectation[1].Day, actual[1]);
...
Assert.AreEqual(expectation[expectation.Count - 1].Day, actual[actual.Count - 1]);
(但没有我在此示例中如何演示的排序限制)。
我正在尝试以这种方式使用@DennisDoomen 建议:
actual.ShouldBeEquivalentTo(
expectation,
options => options.Using<int>(
ctx => ctx.Subject.Should().Be(ctx.Expectation.Day)).WhenTypeIs<int>());
问题是这里的ctx.Expectation
是int
的一个类型,而不是DateTime
,所以我无论如何也不能得到DateTime.Day
。
我在这里错过了什么?
【问题讨论】:
【参考方案1】:ShouldBeEquivalentTo
是您所需要的。默认情况下,它将确保每个集合包含以任何顺序在结构上等效的项目。然后您可以使用Using
/When
选项来定义如何比较Type1
和Type2
。类似的东西:
collection1.ShouldBeEquivalentTo(collection2, options => options
.Using<Type1>(t1 => ctx.Subject.Should().Be(ctx.Expectation)
.WhenTypeIs<Type1>();
【讨论】:
感谢您的回复,@DennisDoomen!在使用您的建议后,我已经用我面临的一个新问题更新了我的问题。 对不起,我从来没有谈过ShouldBeEquivalentTo
,这是你的建议。从我的问题一开始(甚至加粗)我的意思是使用我自己的相等比较器来定义两种不同项目类型之间的自定义相等规则。作为最接近的示例,我指出了.Should().Equal(customers, (c1, c2) => c1.Name == c2.Name)
,它允许使用自定义谓词进行相等检查。所以我的更新不是一个新问题,它只是一个更具体的例子来澄清我的观点。
我很高兴并感谢您的回答 :) 那么有没有办法解决我在 FA 的情况?
不,不是。你可以实现一个自定义的IAssertionRule
并在调用ShouldBeEquivalentTo
时将其添加到options
,但这需要更多的工作。以上是关于比较具有不同项目类型的集合的主要内容,如果未能解决你的问题,请参考以下文章