单元测试 Assert.AreEqual 失败

发布于 2024-11-15 01:17:04 字数 998 浏览 9 评论 0原文

我对从集合中获取对象的方法进行了单元测试。这一直失败,我不明白为什么,所以我在下面创建了一个非常简单的测试来创建 2 个供应商对象并测试它们是否相等,看看我是否可以在代码测试中发现问题。但这次测试再次失败。谁能看到或解释为什么?

    [TestMethod()]
    public void GetSupplierTest2()
    {
        Supplier expected = new Supplier();
        expected.SupplierID = 32532;
        expected.SupplierName = "Test 1"

        Supplier actual = new Supplier();
        actual.SupplierID = 32532;
        actual.SupplierName = "Test 1"

        Assert.AreEqual(expected, actual);
    }

但是如果我测试对象的各个属性,测试就会通过......

    [TestMethod()]
    public void GetSupplierTest2()
    {
        Supplier expected = new Supplier();
        expected.SupplierID = 32532;
        expected.SupplierName = "Test 1"

    Supplier actual = new Supplier();
        actual.SupplierID = 32532;
        actual.SupplierName = "Test 1"

        Assert.AreEqual(expected.SupplierID , actual.SupplierID );
        Assert.AreEqual(expected.SupplierName , actual.SupplierName );
    }

I have a unit test for a method which gets an object from a collection. This keeps failing and I cannot see why, so I have created a very simple test below to create 2 supplier object and test they are equal to see if I can spot the problem in my test of my code. But this test again is failing. Can anyone see or explain why?

    [TestMethod()]
    public void GetSupplierTest2()
    {
        Supplier expected = new Supplier();
        expected.SupplierID = 32532;
        expected.SupplierName = "Test 1"

        Supplier actual = new Supplier();
        actual.SupplierID = 32532;
        actual.SupplierName = "Test 1"

        Assert.AreEqual(expected, actual);
    }

But if I test the individual properties of the objects the test passes...

    [TestMethod()]
    public void GetSupplierTest2()
    {
        Supplier expected = new Supplier();
        expected.SupplierID = 32532;
        expected.SupplierName = "Test 1"

    Supplier actual = new Supplier();
        actual.SupplierID = 32532;
        actual.SupplierName = "Test 1"

        Assert.AreEqual(expected.SupplierID , actual.SupplierID );
        Assert.AreEqual(expected.SupplierName , actual.SupplierName );
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

薔薇婲 2024-11-22 01:17:05

引用类型(即类)的 Object.Equals 默认实现是“引用相等”:这两个对象实际上是相同实例。它不比较字段的值。

要么(如其他人所示)覆盖 Equals 以给出“值相等”。在这种情况下,您还必须重写GetHashCode(以便容器工作),并且应该重写operator ==

或者接受大多数实体应该具有引用相等性(具有相同名称的两个供应商并不总是同一组织)并实际直接使用这些属性。

The default implementation of Object.Equals for reference types (ie. classes) is "Reference Equality": are the two objects actually the same instance. It doesn't compare the values of fields.

Either (as others have shown) override Equals to give "Value Equality". In this caseyou must also override GetHashCode (so containers work), and should override operator ==.

Alternatively accept that most entities should have reference equality (two suppliers with the same name are not always the same organisation) and actually use the properties directly.

烧了回忆取暖 2024-11-22 01:17:05

您比较了供应商类型的 2 个不同实例,这就是断言失败的原因。

如果你想让供应商等于(通过他们的Id),你可以重写Equals方法,这里非常简单的例子,:D。

public class Supplier
{
    private int id;
    private string name;

    public int Id
    {
        get { return id; }
    }

    public string Name
    {
        get { return name; }
    }

    public bool Equals(Supplier other)
    {
        if(other == null) return false;
        return other.id == id;
    }

    public override bool Equals(object obj)
    {
        if(obj == null) return false;
        if (obj.GetType() != typeof (Supplier)) return false;
        return Equals((Supplier) obj);
    }

    public override int GetHashCode()
    {
        return id;
    } 
}

You compare 2 different instances of the Supplier type, that's why Assert fail.

If you want to Supplier are equals say (by their Id) you can override Equals method, here very over simpled example, :D.

public class Supplier
{
    private int id;
    private string name;

    public int Id
    {
        get { return id; }
    }

    public string Name
    {
        get { return name; }
    }

    public bool Equals(Supplier other)
    {
        if(other == null) return false;
        return other.id == id;
    }

    public override bool Equals(object obj)
    {
        if(obj == null) return false;
        if (obj.GetType() != typeof (Supplier)) return false;
        return Equals((Supplier) obj);
    }

    public override int GetHashCode()
    {
        return id;
    } 
}
乖乖 2024-11-22 01:17:05

测试各个属性时,您可以比较字符串/整数值。它们是相等的,因此测试通过了。

在测试父对象时,您仅比较供应商类型的两个容器结构 - 即使它们可能拥有相同的属性值,但它们并不相等:由于您正在实例化两个单独的对象,因此它们不会驻留在内存中的同一地址。

When testing the individual properties, you compare the string/integer values. They are equal, and so the tests pass.

When testing the parent objects, you compare only the two container structures of type Supplier - and even though those may hold equal property values, they are not equal: Since you are instantiating two separate objects, they do not reside at the same address in memory.

情仇皆在手 2024-11-22 01:17:05
//Given the following structure and an instance value, targetObj...

class BaseType
{
   private FeatureType Feature_1;
}

class TargetType : BaseType 
{
  ...
}

TargetType targetObj = new TargetType();

//...a private feature in a specific base class can be accessed as follows

PrivateType typeCast = new PrivateType(typeof( BaseType ));

PrivateObject privateObj = new PrivateObject(targetObj, typeCast);

//...and values can be retrieved and set as follows....

privateObj.SetField("Feature_1", (FeatureType) newValue );

FeatureType result = (FeatureType) privateObj.GetField("Feature_1");

/*
关于在单元测试中访问私有字段的争议,我认为除非绝对必要(即时间和费用管理问题),否则永远不应该使用它。
*/

//Given the following structure and an instance value, targetObj...

class BaseType
{
   private FeatureType Feature_1;
}

class TargetType : BaseType 
{
  ...
}

TargetType targetObj = new TargetType();

//...a private feature in a specific base class can be accessed as follows

PrivateType typeCast = new PrivateType(typeof( BaseType ));

PrivateObject privateObj = new PrivateObject(targetObj, typeCast);

//...and values can be retrieved and set as follows....

privateObj.SetField("Feature_1", (FeatureType) newValue );

FeatureType result = (FeatureType) privateObj.GetField("Feature_1");

/*
With respect to the controversy around accessing private fields in unit tests, I believe it should never be used unless absolutely neccessary (i.e. time and expense management issues).
*/

墨小墨 2024-11-22 01:17:04

正如所有其他答案所说,问题是您试图比较 Supplier 的实例[可能]而不覆盖 Equals 方法。 但我认为您不应该出于测试目的重写 Equals ,因为它可能会影响生产代码,或者您可能需要在生产代码中使用另一个 Equals 逻辑。

相反,您应该像在第一个示例中那样逐一断言每个成员(如果您没有很多地方想要比较整个对象),或者将此比较逻辑封装在某个类中并使用此类:

static class SupplierAllFieldsComparer
{
    public static void AssertAreEqual(Supplier expected, Supplier actual)
    {
        Assert.AreEqual(expected.SupplierID , actual.SupplierID );
        Assert.AreEqual(expected.SupplierName , actual.SupplierName );            
    }
}

//测试代码:

SupplierAllFieldsComparer.AssertAreEqual(expected, actual);

As every other answer says the issue is that you're trying to compare instances of Supplier [probably] without overriding Equals method. But I do not think you should override Equals for test purposes since it may affect production code or you may need another Equals logic in production code.

Instead you should either assert each member one by one as you do it in first sample (if you do not have a lot of places where you want to compare entire object) or encapsulate this comparison logic in some class and use this class:

static class SupplierAllFieldsComparer
{
    public static void AssertAreEqual(Supplier expected, Supplier actual)
    {
        Assert.AreEqual(expected.SupplierID , actual.SupplierID );
        Assert.AreEqual(expected.SupplierName , actual.SupplierName );            
    }
}

// Test code:

SupplierAllFieldsComparer.AssertAreEqual(expected, actual);
無心 2024-11-22 01:17:04

如果您想要比较两个不同的 Supply 实例,并希望在某些属性具有相同值时将它们视为相等,则必须重写 Supplier 上的 Equals 方法,并且比较方法中的这些属性。

您可以在此处阅读有关 Equals 方法的更多信息:http://msdn.microsoft.com /en-us/library/bsc2ak47.aspx

示例实现:

public override bool Equals(object obj)
{
    if (obj is Supplier)
    {
        Supplier other = (Supplier) obj;
        return Equals(other.SupplierID, this.SupplierID) && Equals(other.SupplierName, this.SupplierName);
    }
    return false;
}

请注意,您还会收到编译器警告,提示您还必须实现 GetHashCode,这可能很简单:

public override int GetHashCode()
{
    return SupplierID;
}

If you want to compare two different instances of Supplier, and want them to be considered equal when certain properties have the same value, you have to override the Equals method on Supplier and compare those properties in the method.

You can read more about the Equals method here: http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx

Example implementation:

public override bool Equals(object obj)
{
    if (obj is Supplier)
    {
        Supplier other = (Supplier) obj;
        return Equals(other.SupplierID, this.SupplierID) && Equals(other.SupplierName, this.SupplierName);
    }
    return false;
}

Note that you'll also get a compiler warning that you have to implement GetHashCode as well, that could be as simple as this:

public override int GetHashCode()
{
    return SupplierID;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文