本文介绍了是否NUnit的的Is.EqualTo不从泛型类派生类可靠地工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我跑进与NUnit的以下问题。

Today I ran into the following problem with NUnit.

我有一个类,从一个通用类派生。当
我开始做一些序列化试验和使用NUnit的Is.EqualTo()函数平等的测试。

I have a class, that derives from a generic class.I started to do some serialization tests and tested for equality using the Is.EqualTo() function of NUnit.

我开始怀疑什么是错的,应该已经失败,而不是通过一个测试。当我用obj1.Equals(OBJ2),而不是失败,因为它应该

I started to suspect something is wrong, when a test that should have failed passed instead. When I used obj1.Equals(obj2) instead it failed as it should.

要调查我创建了以下测试:

To investigate I created the following tests:

namespace NUnit.Tests

{

using Framework;

    public class ThatNUnit
    {
        [Test]
        public void IsNotEqualTo_ClientsNotEqual_Passes()
        {
            var client1 = new DerrivedClient();
            var client2 = new DerrivedClient();

            client1.Name = "player1";
            client1.SomeGenericProperty = client1.Name;
            client2.Name = "player2";
            client2.SomeGenericProperty = client2.Name;

            Assert.That(client1.Equals(client2), Is.False);
            Assert.That(client1, Is.Not.EqualTo(client2));
        }

        [Test]
        public void IsNotEqualTo_ClientsAreEqual_AlsoPasses_SomethingWrongHere()
        {
            var client1 = new DerrivedClient();
            var client2 = new DerrivedClient();

            client1.Name = "player1";
            client1.SomeGenericProperty = client1.Name;
            client2.Name = client1.Name;
            client2.SomeGenericProperty = client1.Name;

            Assert.That(client1.Equals(client2), Is.True);
            Assert.That(client1, Is.Not.EqualTo(client2));
        }
    }

    public class DerrivedClient : Client<string>
    {
    }

    public class Client<T>
    {
        public string Name { get; set; }

        public T SomeGenericProperty { get; set; }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            if (obj.GetType() != typeof(Client<T>))
            {
                return false;
            }
            return Equals((Client<T>)obj);
        }

        public bool Equals(Client<T> other)
        {
            if (ReferenceEquals(null, other))
            {
                return false;
            }
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            return Equals(other.Name, Name) && Equals(other.SomeGenericProperty, SomeGenericProperty);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ SomeGenericProperty.GetHashCode();
            }
        }

        public override string ToString()
        {
            return string.Format("{0}, {1}", Name, SomeGenericProperty);
        }
    }
}



二(实际上矛盾的断言)在第二个测试显示问题:

The two (actually conflicting Asserts) in the second test show the problem:

Assert.That(client1.Equals(client2), Is.True);
Assert.That(client1, Is.Not.EqualTo(client2));

此测试将失败的一种方式或其他,但它不会!

This test should fail one way or the other, but it doesn't!

所以我挖一点点进入的NUnit的源代码,才发现,那以后一些if()■对一些特殊情况下,ObjectsAreEqual(对象x,对象y)的方法(最终通过Assert.That被调用(X,Is.EqualTo(Y)),谈到这行代码:

So I dug a little bit into NUnit's source code, only to find, that after some if()s for some special conditions, the ObjectsAreEqual(object x, object y) method (which eventually gets called via Assert.That(x, Is.EqualTo(y)), comes to this line of code:

return x.Equals(y);

我觉得很困惑,因为我现在必须考虑,那是。 EqualTo()只需要一个较长的路线,但基本上应该做一样x.Equals(Y)

I find that very perplexing, since I must now think, that Is.EqualTo() just takes a longer route, but basically should be doing the same as x.Equals(y)

下面对谁感兴趣的完整的方法(NUnit的内.Framework.Constraints命名空间):

Here the full method for whoever is interested (inside the NUNit.Framework.Constraints namespace):

  public bool ObjectsEqual(object x, object y)
    {
        this.failurePoints = new ArrayList();

        if (x == null && y == null)
            return true;

        if (x == null || y == null)
            return false;

        Type xType = x.GetType();
        Type yType = y.GetType();

        if (xType.IsArray && yType.IsArray && !compareAsCollection)
            return ArraysEqual((Array)x, (Array)y);

        if (x is ICollection && y is ICollection)
            return CollectionsEqual((ICollection)x, (ICollection)y);

        if (x is IEnumerable && y is IEnumerable && !(x is string && y is string))
            return EnumerablesEqual((IEnumerable)x, (IEnumerable)y);

        if (externalComparer != null)
            return externalComparer.ObjectsEqual(x, y);

        if (x is string && y is string)
            return StringsEqual((string)x, (string)y);

        if (x is Stream && y is Stream)
            return StreamsEqual((Stream)x, (Stream)y);

        if (x is DirectoryInfo && y is DirectoryInfo)
            return DirectoriesEqual((DirectoryInfo)x, (DirectoryInfo)y);

        if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y))
            return Numerics.AreEqual(x, y, ref tolerance);

        if (tolerance != null && tolerance.Value is TimeSpan)
        {
            TimeSpan amount = (TimeSpan)tolerance.Value;

            if (x is DateTime && y is DateTime)
                return ((DateTime)x - (DateTime)y).Duration() <= amount;

            if (x is TimeSpan && y is TimeSpan)
                return ((TimeSpan)x - (TimeSpan)y).Duration() <= amount;
        }

        return x.Equals(y);
    }



那么,什么是怎么回事,以及如何可以把它固定?

So what is going on here and how can it be fixed?

我希望能够信任我的测试,因此必然再次NUnit的。

I want to be able to trust my tests and thus necessarily NUnit again.

我也不想开始使用equals()而不是Is.EqualTo()(当测试失败前不给我这么好的输出。)

I also don't want to start using Equals() instead of Is.EqualTo() (the former doesn't give me such a nice output when the test fails).

在此先感谢

更新:

在此期间,我这个问题进一步搏斗,发现了类似的问题的并张贴了可能的。

In the meantime I wrestled further with this problem and found a similar problem here and posted a possible workaround.

推荐答案

问题是,第二次测试的第二个断言调用等于接受了对象超载而非客户端< T> ,所以这对比返回false:

The problem is that the second assertion of the second test calls the Equals overload that accepts an object rather than a Client<T>, so this comparison returns false:

// obj.GetType() returns Client.DerrivedClient

if (obj.GetType() != typeof(Client<T>))
{
    return false;
}

要解决这个问题,你可以改变比较运算这样:

To fix this, you can change the comparison operation to this:

if (obj.GetType() != this.GetType())

这篇关于是否NUnit的的Is.EqualTo不从泛型类派生类可靠地工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 23:53