I would like to "combine" the assertions and assertions of the Fluent Assertion collection, for example. argue that two IEnumerable are pairwise equal, using a property by property (possibly "nested") comparison (ie, structural equality, in the language of a functional language).
Specific example:
var dic = new Dictionary<int, string>() { {1, "hi"}, {2, "bye" } }; var actual = dic.ToSelectListItems(0).OrderBy(si => si.Text); var expected = new List<SelectListItem>() { new SelectListItem() {Selected = false, Text="bye", Value="2"}, new SelectListItem() {Selected = false, Text="hi", Value="1"} };
Here I wrote a ToSelectListItems extension method that converts a Dictionary to IEnumerable from SelectListItem (from ASP.NET MVC). I want to argue that actual and expected "structurally" equal, noting that the reference type SelectListItem does not override Equal and therefore uses reference equality by default.
Update
The following manual solution is currently being used, still hoping for something better built into FluentAssertions:
public static void ShouldBeStructurallyEqualTo<T, U>(this IEnumerable<T> actual, IEnumerable<U> expected) { actual.Should().HaveCount(expected.Count()); actual.Zip(expected).ForEach(pair => pair.Item1.ShouldHave().AllProperties().IncludingNestedObjects().EqualTo(pair.Item2)); }
(note: Zip is my own IEnumerable extension, which uses Tuple.Create as the default projection)
Update 2
Here are two minimal examples:
public class FooBar { public string Foo { get; set; } public int Bar { get; set; } } public class TestClass { [Test] public void MinimalExample() { List<FooBar> enumerable1 = new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } }; List<FooBar> enumerable2 = new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } }; enumerable1.ShouldHave().SharedProperties().IncludingNestedObjects().EqualTo(enumerable2);
c # unit-testing nunit fluent-assertions
Stephen swensen
source share