繁体   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