问题
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);
}
回答1:
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.
回答2:
In later versions of FluentAssetrions one can use 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.
Works in version that I use (FluentAssertions.2.2.0.0).
回答3:
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
}
回答4:
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);
来源:https://stackoverflow.com/questions/9877644/can-fluent-assertions-use-a-string-insensitive-comparison-for-ienumerablestring