[英]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.