我对一个从集合中获取对象的方法进行了单元测试。这一直在失败,我不明白为什么,所以我在下面创建了一个非常简单的测试来创建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 );
}
答案 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");
/ * 关于在单元测试中访问私有字段的争议,我认为除非绝对必要(即时间和费用管理问题),否则不应该使用它。 * /