簡體   English   中英

單元測試 Assert.AreEqual 失敗

[英]Unit Test Assert.AreEqual failed

我對從集合中獲取 object 的方法進行了單元測試。 這一直失敗,我不明白為什么,所以我在下面創建了一個非常簡單的測試來創建 2 個供應商 object 並測試它們是否相等,看看我是否可以在我的代碼測試中發現問題。 但是這個測試又失敗了。 任何人都可以看到或解釋原因嗎?

    [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 );
    }

正如所有其他答案所說,問題是您正在嘗試比較Supplier的實例 [可能] 而不覆蓋Equals方法。 但是我認為您不應該出於測試目的覆蓋Equals因為它可能會影響生產代碼,或者您可能需要在生產代碼中使用另一個Equals邏輯。

相反,您應該在第一個示例中逐個聲明每個成員(如果您沒有很多地方要比較整個對象),或者將此比較邏輯封裝在一些 class 中並使用此 class:

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

如果要比較 Supplier 的兩個不同實例,並希望在某些屬性具有相同值時將它們視為相等,則必須覆蓋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;
}

引用類型(即類)的Object.Equals的默認實現是“引用相等”:這兩個對象實際上是同一個實例。 它不比較字段的值。

要么(如其他人所示)覆蓋Equals以給出“價值平等”。 在這種情況下,您還必須覆蓋GetHashCode (這樣容器才能工作),並且應該覆蓋operator ==

或者接受大多數實體應該具有引用相等性(具有相同名稱的兩個供應商並不總是同一個組織)並實際直接使用這些屬性。

您比較了 Supplier 類型的 2 個不同實例,這就是 Assert 失敗的原因。

如果你想 Supplier 是平等的說(通過他們的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;
    } 
}

測試單個屬性時,您比較字符串/整數值。 它們是相等的,因此測試通過。

測試父對象時,您只比較供應商類型的兩個容器結構 - 即使它們可能具有相同的屬性值,它們也不相等:由於您正在實例化兩個單獨的對象,它們不在 memory 中的相同地址.

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

/* 關於在單元測試中訪問私有字段的爭議,我認為除非絕對必要(即時間和費用管理問題),否則不應該使用它。 */

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM