15

I've got a pair of Lists I'm trying to compare using Fluent Assertions. I can code up a comparison easily, but I'd like to use Fluent Assertions so that I can get the reason to show up in the test failed message.

Everything I've seen so far seems to using the default Object.Equals comparison, which is case-sensitive. I can't seem to pass an IComparer to the Equal or Contains methods, so 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);
}
Zugbo
  • 514
  • 1
  • 4
  • 14

4 Answers4

31

In later versions of Fluent Assertions, one can use following:

stringValue.Should().BeEquivalentTo(stringToCompare);

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.

  • FluentAssertions 2.2.0.0

Which works in the version that I use.

Bennett Yeo
  • 819
  • 2
  • 14
  • 28
TarasB
  • 2,407
  • 1
  • 24
  • 32
  • Now I have the opposite question: I need it to see casing differences. Am I stuck with my own handwritten comparison and then checking result being true/false? – ecth Aug 01 '22 at 09:30
3

We could add an optional lambda expression to the Equal() method. Then, you could 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))
} 

A IComparer would also be possible, but I think the occasional exception to Equal()'s default behavior wouldn't warrant an additional custom-written class. In fact, a separate IComparer might ever obscure the intention of the test. Let me know what you guys think is the best solution, so I can add it as an issue on Codeplex for release 1.8.0.

Dennis Doomen
  • 8,368
  • 1
  • 32
  • 44
1

How about adding a new Fluent assertion via an extention method (or two)? I've written code to add a .EqualInsensitively(...) to the available fluent assertions for a collection of strings.

I've put the code to implement this on an external pastebin because its a little long and the MS-PL might 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
}
dplante
  • 2,445
  • 3
  • 21
  • 27
Kevin Cathcart
  • 9,838
  • 2
  • 36
  • 32
0

you could wirte a extension method for IEnumerable<string> yourself (this is how I do this stuff) and I thing some Unit-Testframeworks already do so (FSUnit AFAIK)

Here is a simple example (you could improve a lot - but it should do)

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);
Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • 1
    "I can code up a comparison easily, but I'd like to use Fluent Assertions" – bzlm Mar 26 '12 at 18:50
  • If I do have to write code, this is probably the way I'd do it, but ideally someone is going to show me some method I hadn't seen yet in the library. – Zugbo Mar 26 '12 at 18:56