【问题标题】:NUnit Assert.Equals What am I missing?NUnit Assert.Equals 我错过了什么?
【发布时间】:2010-11-08 06:55:26
【问题描述】:

Assert.Equals() 从不调用

Equals()
operator ==
operator !=

我错过了什么吗?我已经实现了 IEquatable,但在使用 nunit 时仍然不会调用这些方法。

if (objectA != objectB) Assert.Fail(); //doesnt fail
if (!objectA.Equals(objectB)) Assert.Fail(); //doesnt fail
Assert.AreEqual(objectA, objectB); //fail

更新

我应该更清楚。

public class Entity 
{
  public int ID { get; set; }
}

var objectA = new Entity() { ID = 1 };
var objectB = new Entity() { ID = 1 };

两个独立的实例都具有相同的 ID 我已经实现了所有相关的方法,以使其适用于 ==、!= 和 Equals,但 nunit AreSame 和 AreEqual 仍然无法调用这些方法。

【问题讨论】:

  • 我也有同样的问题。现在我正在使用 Assert.IsTrue(objectA.Equals(objectB));
  • 我有同样的问题,我已经确定如果我比较的对象是相同的引用,它会起作用。即创建 2 个具有不同属性的对象,除了相等比较的属性,然后 Assert.Equals 工作......如果它正在比较相同的引用(肯定是相等的),那么它会失败!因为不相等(NUnit 2.5)
  • 你在找Assert.AreEqual(objA, objB);

标签: nunit


【解决方案1】:

Assert.AreEqual(a, b) 用于值类型,Assert.AreSame(a, b) 用于引用类型。 http://www.nunit.org/index.php?p=identityAsserts&r=2.2.7

【讨论】:

  • 这仍然说由于某种原因它们不一样..(它不会调用我的相等方法):(我要测试的是同一个类的 2 个实例具有相同的 ID,应该说是的,他们是平等的。
  • 不确定,你当然可以做 Assert.IsTrue(objectA == objectB) 但我不知道你为什么需要。
  • Assert.AreSame(a, b) 实际上是在执行ReferenceEquals(a,b),可能不是您想要的。如果要断言相同的对象实例,请使用此方法。否则,您最好改用Assert.AreEqual(a,b)
【解决方案2】:

你绝对是对的。 我今天早些时候与similar problem 搏斗,直到我找到您的帖子并且现在确定,NUnit IsEqualTo() 并没有始终如一地调用提供的 Equals 覆盖。

我一直这么说,因为有时确实如此。事实上,我有两节课。第二个是从第一个衍生出来的。当我在第一个实例上调用 Is.EqualTo() 时,NUnit 调用 Equals 覆盖,对于第二个实例它不会。

虽然这很奇怪,但我没有时间进一步调查发生了什么。

有类似问题或解决方案的人绝对应该发布它,因为这是一件非常烦人的事情,实际上让我怀疑我的测试的有效性。

与此同时,我创建了以下 Affirm 类,它肯定会调用 Equals 覆盖(我检查了它)。它使用 NUnit 代替 Is.EqualTo() 来做一个简单的相等 Assert 并且在一定程度上弥补了这样一个事实,即在测试失败的情况下,NUnit 不会给出对象的字符串表示。

原来是这样:

using NUnit.Framework;

public static class Affirm
{
    public static Affirmer That(object actual)
    {
        return new Affirmer(actual);
    }
}

[EditorBrowsable(EditorBrowsableState.Never)]
public class Affirmer
{
    readonly object _actual;

    public Affirmer(object actual)
    {
        _actual = actual;
    }

    public void IsEqualTo(object expected)
    {
        string failureMessage = string.Format("\nExpected: <{0}>\nBut was:  <{1}>", _actual, expected);
        Assert.That(_actual.Equals(expected), Is.True, failureMessage);
    }

    public void IsNotEqualTo(object expected)
    {
        string failureMessage = string.Format("\nDid not excpect: <{0}>\nBut was:         <{1}>", _actual, expected);
        Assert.That(_actual.Equals(expected), Is.False, failureMessage);
    }
}

像这样使用它:

Affirm.That(actualObject).IsEqualTo(expectedObject);

Affirm.That(actualObject).IsNotEqualTo(expectedObject);

希望这会有所帮助。

【讨论】:

  • 为了完整起见:从您的原始帖子 (stackoverflow.com/questions/1624848/…) 中可以看出,您的问题是由覆盖 object.Equals (object) 中的错误引起的。 (我猜这个线程的OP的问题是由类似的错误引起的。)
  • @FabianSchmied 我不认为这是由于 equals 方法中的错误,因为他说 Nunit 甚至从未调用过他的 equals 方法。我带着同样的问题来到这里。如果 Nunit 没有调用 Equals 方法,那么我在 Equals 方法中所做的更改并不重要
  • 我有同样的问题,但在我自己在课堂上实施 Equals 之前,我的测试有效。既然我有一个 Equals 方法,肯定是有什么东西说服了 NUnit调用我的 Equals 方法。我不认为我准备好调查代码,因为我可以通过使用 Assert.IsTrue(obj1.Equals(obj2))
  • @PandaWood Thorsten Lorenz 的示例有两种Equals 方法:一种采用object 类型的参数,另一种采用基类类型的参数。 NUnit 调用类型为object 的那个。这个方法有一个错误:它包含一个不考虑子类的类型检查。解决方案是修复该类型检查。请参阅accepted answer
【解决方案3】:

某些框架允许在分配 Id 之前(即实体未保存)与之后以不同的方式工作,当它明确的意图是实体 ID 是质量的唯一基础时。您是在使用某种框架还是 Entity 是您自己的类?

如果是你自己的类,你能展示你的 Equals() 逻辑的要点吗?

干杯, 浆果

仅供参考 Assert.AreSame 绝不是用于验证您的 IEquatable 实现的测试!请参阅帮助文档中的 ReferenceEquals 以更好地理解该断言。

【讨论】:

  • +1 for "Assert.AreSame 永远不是验证您的 IEquatable 实现的测试"
【解决方案4】:

如果 Equals 方法被正确覆盖,它应该可以工作(参见related question)。您的 Equals 方法是否有问题(尽管如果它仅由 int 比较组成,我认为不会)?可能值得在您的 Equals 方法中设置一个断点,然后运行测试以查看幕后发生的情况。

【讨论】:

    【解决方案5】:

    你可能想看看这个问题: NUnit's Assert.Equals throws exception "Assert.Equals should not be used for assertions"

    tl;博士; Assert.Equals(obj1, obj2) 被 NUnit 覆盖,并引发异常。你应该改用Assert.AreEqual(obj1, obj2)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-11
      相关资源
      最近更新 更多