FluentAssertion не удалось сравнить перечисляемые строки
Этот код работает нормально
[Test]
public void boo()
{
var collection = new[] { 1, 2, 3 };
collection.Should().Equal(1, 2, 3);
}
Но это не удается
[Test]
public void foo()
{
var collection = new[] { "1", "2", "3" };
collection.Should().Equal("1", "2", "3");
}
Сообщение об ошибке:
'Ожидаемая коллекция будет равна {1}, потому что 2, но {"1", "2", "3"} содержит 2 элементов слишком много.'
Что здесь не так? Почему перечисляемая строка не может быть сравнена?
И, конечно же, мой вопрос - как обрабатывать case в foo()?
4 ответа
Это происходит потому, что компилятор выбирает неправильную перегрузку Equals() из-за ограничений в C#. В вашем конкретном случае он принимает Equals (ожидаемая строка, причина строки, params string[] args) вместо Equals(IEnumerable). Я никогда не находил простой способ решить эту двусмысленность в FluentAssertions.
Чтобы решить вашу проблему, оберните ожидаемые значения в массив.
[Test]
public void foo()
{
var collection = new[] { "1", "2", "3" };
collection.Should().Equal(new[] {"1", "2", "3"});
}
Проблема заключается в том, что второй вызов разрешается до следующей перегрузки:
public AndConstraint<TAssertions> Equal(IEnumerable expected,
string reason,
params object[] reasonArgs);
Вместо:
public AndConstraint<TAssertions> Equal(params object[] elements);
Чтобы получить желаемый результат, вы можете принудительно настроить компилятор на правильный метод перегрузки, например, выполнив:
collection.Should().Equal((object)"1", "2", "3");
Что происходит с тестом:
[Test]
public void foo()
{
const string one = "1";
const string two = "2";
const string three = "3";
var collection = new[] { one, two, three };
collection.Should().Equal(one, two, three);
}
Я предполагаю, как Кенни признал в комментарии, что вы выполняете ссылочное равенство, когда эти строки не совпадают.
Попробуйте вместо этого SequenceEquals?
http://msdn.microsoft.com/en-us/library/bb342073.aspx
И метод Equals просто сравнивает ссылки на равенство.
Вот строка из юнит-теста в одном из моих проектов:
Assert.IsTrue(expected.OrderBy(x => x).SequenceEqual(actual.OrderBy(x => x)));
Все элементы в "ожидаемом" и "фактическом" реализуют IEQuatable.