我为某些单位测试写了一个辅助方法,以使用自定义IEqualityComparer<T>
实现:
/// <summary>
/// Known issue: this checks for set-equality, which means that duplicate items will be interpreted as one.
/// </summary>
public static void AssertCollectionsAreEquivalent<T>(ICollection<T> expected, ICollection<T> actual,
IEqualityComparer<T> comparer)
{
T[] commonMembers = expected.Intersect(actual, comparer).ToArray();
T[] missingMembers = expected.Except(actual, comparer).ToArray();
T[] extraMembers = actual.Except(expected, comparer).ToArray();
if (missingMembers.Any() || extraMembers.Any())
{
Assert.Fail("Collections were not equivalent.{0}Common members: {1}{0}Missing members: {2}{0}Extra members: {3}",
Environment.NewLine,
string.Join(", ", commonMembers.Select(t => t.ToString())),
string.Join(", ", missingMembers.Select(t => t.ToString())),
string.Join(", ", extraMembers.Select(t => t.ToString())));
}
}
在此过程中,允许呼叫者提供可以提供自定义字符串格式的对象似乎很有帮助,但是我在.NET中没有看到适合账单的接口。我目前暂时使用了Func<T, string>
:
/// <summary>
/// Known issue: this checks for set-equality, which means that duplicate items will be interpreted as one.
/// </summary>
private static void AssertCollectionsAreEquivalent<T>(ICollection<T> expected, ICollection<T> actual,
IEqualityComparer<T> comparer, Func<T, string> toStringConverter)
{
T[] commonMembers = expected.Intersect(actual, comparer).ToArray();
T[] missingMembers = expected.Except(actual, comparer).ToArray();
T[] extraMembers = actual.Except(expected, comparer).ToArray();
if (missingMembers.Any() || extraMembers.Any())
{
Assert.Fail("Collections were not equivalent.{0}Common members: {1}{0}Missing members: {2}{0}Extra members: {3}",
Environment.NewLine,
string.Join(", ", commonMembers.Select(toStringConverter)),
string.Join(", ", missingMembers.Select(toStringConverter)),
string.Join(", ", extraMembers.Select(toStringConverter)));
}
}
动机是一个单位测试套件,该套件使用通用测试DTO从数据存储中检索项目,但是对于不同的测试场景,我们对平等的定义有不同的定义(因此IEqualityComparer<T>
参数)。我知道我可以定义一个自定义界面来完成我想做的事情:
public interface IToStringProvider<in T>
{
string ToString(T obj);
}
...但是我希望可能有一些现有的物品适合账单。
查看IFormattable
。它可能会做您想要的,尽管并不完全相同。您可能需要在该方法上添加类型约束,但是您会发现已经实现了很多类型。