Can Fluent Assertions use string-insensitive comparisons for IEnumerable <string>?
I have a couple of lists that I'm trying to compare using Fluent Assertions. I can easily match the comparison, but I would like to use Fluent Assertions so that I can explain the reason for the error message.
Everything I've seen so far seems to use the default Object.Equals comparison, which is case sensitive. I cannot pass IComparer to Equal or Contains methods, is there any other way?
[TestMethod()] public void foo() { var actual = new List<string> { "ONE", "TWO", "THREE", "FOUR" }; var expected = new List<string> { "One", "Two", "Three", "Four" }; actual.Should().Equal(expected); } We could add an optional lambda expression to the Equal () method. Then you can do something like
[TestMethod()] public void foo() { var actual = new List<string> { "ONE", "TWO", "THREE", "FOUR" }; var expected = new List<string> { "One", "Two", "Three", "Four" }; actual.Should().Equal(expected, (o1, o2) => string.Compare(o1, o2, StringComparison.InvariantCultureIgnoreCase)) } IComparer may be possible, but I believe that accidentally excluding Equal () from the default behavior does not guarantee an additional custom class. In fact, a single IComparer may ever obscure the intent of the test. Let me know what you guys think is the best solution, so I can add it as a problem for Codeplex for version 1.8.0.
In later versions of FluentAssetrions, you can use the following:
stringValue.Should().BeEquivalentTo(stringToCompare); Summary from [metadata]:
// Summary: // Asserts that a string is exactly the same as another string, including any // leading or trailing whitespace, with the exception of the casing. It works in the version I'm using (FluentAssertions.2.2.0.0).
How to add a new Fluent statement using an extension method (or two)? I wrote code to add .EqualInsensitively(...) to the available free statements for a collection of strings.
I put the code to implement this on an external pastebin , because it is a bit longer, and MS-PL may not be compatible with CC wiki.
Use something like this:
private static void Main() { var mylist = new List<string> {"abc", "DEF", "GHI"}; mylist.Should().EqualInsensitively(new[] {"AbC", "def", "GHI"}) .And.NotContain(string.Empty); //Emaple of chaining } you could use the extension method for IEnumerable<string> yourself (this is how I do it) and I think some Unit-Testframeworks already do this (FSUnit AFAIK)
Here is a simple example (you can improve a lot - but he has to do it)
public static AssertEqualSetCaseInsensitive(this IEnumerable<string> actual, IEnumerable<string> expected) { if (actual.Count() != expected.Count()) Assert.Fail("not same number of elements"); if (!actual.All(a => expected.Any(e => e.ToLower() == a.ToLower())) Assert.Fail("not same sets"); } just use like
actual.AssertEqualSetCaseInsensitive(expected);