NUnit - 等于(这个,那个),True(这个==那个)还是那个(这个,Is.EqualTo(那个))?

Jea*_*anz 1 c# nunit

我们的内部框架使用通用类DBField<T>来模拟具有与实体框架不兼容的数据库(例如 Oracle 11 或 Sybase)的实体字段。

我们试图使其尽可能透明(再次,像实体字段一样),以便以下代码可以工作:

    DBField<int?> z_intLength = 2;
    while (z_intLength <= 5)
    {
        z_intLength++;
    }

    //[...]

    DBField<int?> z_intMaxLength = 10;
    if (z_intLength > z_intMaxLength)
    {
    }
Run Code Online (Sandbox Code Playgroud)

上面的效果很好。我们使用了public static implicit operator DBField<T>(T value)and public static implicit operator T(DBField<T> value),以及覆盖==和其他比较运算符,以及实现IEquatable<DBField<T>>IComparableIComparable<DBField<T>>

现在我们正在尝试进行DBField<T>NUnit 测试,在这方面我们还很陌生。

值得注意的是,我们正在尝试各种等效方案:

            string z_strComment = "Comment";
            _objOrder2.OrderComment = z_strComment;

            //[...]

            Assert.True("Comment" == _objOrder2.OrderComment);
            Assert.That("Comment", Is.EqualTo(_objOrder2.OrderComment));
            Assert.That(_objOrder2.OrderComment, Is.EqualTo("Comment"));
            Assert.Equals("Comment", _objOrder2.OrderComment);
Run Code Online (Sandbox Code Playgroud)

前两个断言通过,后两个断言失败。

  1. 每个断言的内部运作似乎都有所不同。有人可以解释它是什么吗?

  2. 更准确地说,使用断点进行调试似乎表明Assert.That("Comment", Is.EqualTo(_objOrder2.OrderComment))测试_objOrder2.OrderComment.Equals("Comment");我倒是期待相反的情况。我错过了什么吗?

  3. 我明白这一点True()并且Equals()年龄大于That()。在哪些情况下哪些是优选的?

can*_*on7 5

这里有两件事在起作用:

  1. 如果测试失败,来自 NUnit 的错误消息有多有用
  2. 您正在使用什么风格的 NUnit API

Assert.True("Comment" == _objOrder2.OrderComment)
Run Code Online (Sandbox Code Playgroud)

如果此测试失败,您会收到类似“预期为真,结果为假”的消息。没有帮助,因为它没有告诉您_objOrder2.OrderComment实际的价值是什么。


Assert.Equals("Comment", _objOrder2.OrderComment);
Assert.That(_objOrder2.OrderComment, Is.EqualTo("Comment"));
Run Code Online (Sandbox Code Playgroud)

这两个是等价的,第一个使用稍微短的语法,第二个使用更可扩展的约束模型(您可以编写自己的断言,例如Assert.That(x, new MyConstraint(y)))。

如果测试失败,你会得到类似的信息Expected "Comment", was "Actual Value"。这更有帮助一点。


Assert.That("Comment", Is.EqualTo(_objOrder2.OrderComment));
Run Code Online (Sandbox Code Playgroud)

这个是倒退的 如果失败,你会得到类似 的信息Expected "Actual Value", was "Comment",这是错误的。


关于旧式模型Assert.Equals与约束模型Assert.That,它(令人烦恼地)取决于个人喜好。我个人使用它是Assert.Equals因为我发现它更容易阅读,但是在对集合进行断言时我会使用Assert.Thatover ,并且在编写我自己的断言时我也会使用它。CollectionAssert

请阅读下面一位 NUnit 开发人员的评论,了解他们如何发现用户发现该Assert.That样式更容易理解。

  • 很好的答案!我要补充一点,旧的“Assert.Equals”导致了正确顺序的混乱。对于具有其他框架经验的开发人员来说,将期望值放在第一位似乎是很自然的事情,这些框架也做同样的事情。我们发现以实际值作为第一个参数的“Assert.That”更容易被大多数用户理解,因为它模仿了英语以及许多欧洲语言的自然语言顺序。当然,大多数人在习惯了事物后就会觉得很自然。:-) (3认同)
  • @Jean-DavidLanz 实际上,经典断言和基于约束的断言都使用相同的实现......它们只是内部实现之上的语法。事实上,当引入基于约束的断言时,所有经典断言都被重写,以便它们实际上调用基于约束的模型。至于为什么它使用“expected.Equals”...那是因为测试作者始终知道预期值的类型,而实际值的类型可能不知道。 (2认同)
  • 另外,请记住,NUnit 有自己的相等定义,这与数学和通常的编程语言相等有细微的不同。这似乎是合理的,因为在测试中如何使用相等断言。特别是,断言相等性在副作用(例如错误消息)和实际结果(例如,如果内容相同时两个数组相等)方面都是不对称的。不幸的是,这是一个微妙的问题,通常要到使用几年后才会被发现。:-( (2认同)