【发布时间】:2015-05-13 15:15:14
【问题描述】:
我为一些单元测试编写了一个辅助方法,以使用自定义 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);
}
...但我希望可能有一些现有的项目可以满足要求。
【问题讨论】:
-
是的,但这会检查序列相等(相同的项目,相同的顺序),我真的只想要集合平等(相同的项目,任何顺序)。我知道我的示例实现了集合相等;我会在以后更新它,以便正确处理重复的项目。
-
不确定为什么有人会对此投反对票。似乎措辞良好,代码示例等......
标签: .net interface string-formatting