これは古い質問であることは知っていますが、偶然見つけたので、利用可能な新しいソリューションを検討することにしました (少なくとも .net Core 2.0 ソリューションの xunit 2.3.1 では)。
いつ導入されたのかはわかりませんが、3 番目のパラメーターとして の.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();
}
}
編集:実際の値と期待される値を比較することは!=
、特定の型では効果的ではないことがわかりました(参照型と値型の違いに関するより良い説明があると確信していますが、それは今日ではありません)。メソッドを使用して 2 つの値を比較するようにコードを更新したところ、.Equals
はるかにうまく機能するようです。