I have two collections with different item types, for example:
var collection1 = new List<Type1>();
var collection2 = new List<Type2>();
Is it possible to assert that two collections with different item types contain equal items in any order using my own equality comparer with the FluentAssertions?
The most related example from the official FA documentation considers that both collections are the same type:
persistedCustomers.Should().Equal(customers, (c1, c2) => c1.Name == c2.Name);
One possible solution to use this approach for my situation is to create a new List<Type1>
collection based on items from the collection2
and use it instead of customers
in the example above.
But sometimes it's just not possible and actually smells like an overhead.
I'm wondering if there is a similar approach that uses FA elegance like the above one but suitable for the collections with different item types?
UPDATE 1 (trying to use @DennisDoomen suggestion):
Let's take more specific example.
Suppose we have a List<DateTime>
of expected values that represents dates of a single month:
var expectation = new List<DateTime>();
A testing method returns a List<int>
of day numbers:
var actual = new List<int>();
We want to assert that the set of day numbers returned by testing method is the same as a set composed from DateTime.Day values of the expectation list, i.e.:
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]);
(but without the ordering restriction which I don't how to demonstrate in this example).
I'm trying to use @DennisDoomen suggestion in this way:
actual.ShouldBeEquivalentTo(
expectation,
options => options.Using<int>(
ctx => ctx.Subject.Should().Be(ctx.Expectation.Day)).WhenTypeIs<int>());
The problem is that ctx.Expectation
here is a type of int
, not a DateTime
, so I can't get DateTime.Day
anyhow.
What am I missing here?
ShouldBeEquivalentTo
is what you need. By default it will ensure that each collection contains items that are structurally equivalent in any order. You can then use the Using
/When
options to define how Type1
and Type2
should be compared. Something like:
collection1.ShouldBeEquivalentTo(collection2, options => options
.Using<Type1>(t1 => ctx.Subject.Should().Be(ctx.Expectation)
.WhenTypeIs<Type1>();