Я знаю, что это старый вопрос, но поскольку я наткнулся на него, я подумал, что взвесу новое доступное решение (по крайней мере, в xunit 2.3.1 в решении .net Core 2.0).
Я не уверен, когда это было введено, но теперь существует перегруженная форма .Equal, которая принимает экземпляр IEqualityComparer<T> в качестве третьего параметра. Вы можете создать собственный компаратор в своем модульном тесте, не загрязняя им свой код.
Следующий код можно вызвать следующим образом: Assert.Equal(expectedParameters, parameters, new CustomComparer<ParameterValue>());
Похоже, что XUnit по умолчанию прекращает обработку теста, как только обнаруживается сбой, поэтому запуск нового EqualException из нашего компаратора, похоже, соответствует тому, как XUnit работает из коробки.
public class CustomComparer<T> : IEqualityComparer<T>
{
public bool Equals(T expected, T actual)
{
var props = typeof(T).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in props)
{
var expectedValue = prop.GetValue(expected, null);
var actualValue = prop.GetValue(actual, null);
if (!expectedValue.Equals(actualValue))
{
throw new EqualException($"A value of \"{expectedValue}\" for property \"{prop.Name}\"",
$"A value of \"{actualValue}\" for property \"{prop.Name}\"");
}
}
return true;
}
public int GetHashCode(T parameterValue)
{
return Tuple.Create(parameterValue).GetHashCode();
}
}
Изменить: я обнаружил, что сравнение фактических и ожидаемых значений с != не было эффективным для определенных типов (я уверен, что есть лучшее объяснение, связанное с различием между ссылочными типами и типами значений, но это не на сегодня). Я обновил код, чтобы использовать метод .Equals для сравнения двух значений, и, похоже, он работает намного лучше.
person
Engineer_Andrew
schedule
13.04.2018
Assert.Same()сравнивает по ссылке; он утверждает, чтоObj1иObj2являются одним и тем же объектом, а не просто выглядят одинаково. - person TeaDrivenDev   schedule 12.05.2014