单元测试Assert.AreEqual失败

时间:2011-06-13 08:35:10

标签: .net unit-testing mstest assert

我对一个从集合中获取对象的方法进行了单元测试。这一直在失败,我不明白为什么,所以我在下面创建了一个非常简单的测试来创建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 );
    }

6 个答案:

答案 0 :(得分:22)

正如其他所有答案都说的那样,问题在于您尝试比较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);

答案 1 :(得分:4)

如果要比较供应商的两个不同实例,并希望在某些属性具有相同值时将它们视为相等,则必须覆盖Equals上的Supplier方法并比较这些属性在方法中。

您可以在此处详细了解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;
}

答案 2 :(得分:3)

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

(正如其他人所示)覆盖Equals以赋予“价值平等”。在这种情况下,您还必须覆盖GetHashCode(以便容器正常工作),并且应该覆盖operator ==

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

答案 3 :(得分:2)

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

如果您希望供应商等于(通过 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;
    } 
}

答案 4 :(得分:1)

测试单个属性时,比较字符串/整数值。它们是平等的,所以测试通过了。

在测试父对象时,只比较两个类型为Supplier的容器结构 - 即使它们可能包含相同的属性值,它们也不相等:由于您要实例化两个单独的对象,它们不会同时存在记忆中的地址。

答案 5 :(得分:0)

//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");

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