在NUnit中覆盖ToString而无需访问源代码

时间:2016-07-13 12:20:21

标签: c# nunit

我有一个来自第三方库的类Foo,我使用NUnit检查是否与另一个实例相等,

Assert.AreEqual(foo1, foo2);

当对象不同时,我得到预期的失败,

Expected: Foo
But was: Foo

但错误信息并非有用。我知道NUnit使用ToString来显示错误消息,但我无法覆盖此处。

NUnit是否提供API来覆盖此行为,以便我可以提供自己的ToString实现?我在Assert.AreEqualAssert.That API

上看不到任何内容

3 个答案:

答案 0 :(得分:8)

您可以为任何类型添加特定的格式代码,NUnit将使用它。见https://github.com/nunit/docs/wiki/TestContext#addformatter

此功能已在NUnit 3.2中添加。

答案 1 :(得分:2)

这可能不是一个好方法,但您可以将值包装在另一个类中,并在那里覆盖ToString()。例如,在测试夹具中,创建以下私有类:

private class ValueWrapper
{
    private readonly OtherClass _wrapped;

    public ValueWrapper(OtherClass wrapped)
    {
        _wrapped = wrapped;
    }

    public override bool Equals(object obj)
    {
        // Compare the wrapped objects for equality.
        // This needs some beefing up for null checks, type checks, etc.
        return _wrapped.Equals(obj._wrapped);
    }

    public override string ToString()
    {
        return "whatever you like";
    }
}

有了这个包装类,你可以将你的预期&实际值并将其传递给断言。对于CollectionAssert,您可以使用Select() LINQ子句将集合中的每个元素转换为其中一个元素。

答案 2 :(得分:0)

使用接受的答案,我将以下代码组合在一起以对失败的约束进行json序列化(使用Json.NET):

TestContext.AddFormatter(obj =>
{
    if (obj == null)
        return x => "";

    return x => JsonConvert.SerializeObject(x);
});