1

my main target was to compare data stored in DB and in XLSX file.

To do that, I have two lists created following way:

private class ProductList
{
    public string productSku { get; set; }
    public string productName { get; set; }
    public string productSubfamilyId { get; set; }
    public string productSubfamilyName { get; set; }
    public string productFamilyId { get; set; }
    public string productFamilyName { get; set; }
};

(...)
List<ProductList> productListsDB = new List<ProductList>();
List<ProductList> productListsXLSX = new List<ProductList>();
(...)

To first one, I provide data directly from SQL query result:

while (reader.Read())
{
    ProductList pl = new ProductList();
    pl.productSku = reader.GetString(reader.GetOrdinal("ProductSku"));
    pl.productName = reader.GetString(reader.GetOrdinal("ProductName"));
    pl.productSubfamilyId = reader.GetString(reader.GetOrdinal("ProductSubfamilyId"));
    pl.productSubfamilyName = reader.GetString(reader.GetOrdinal("ProductSubfamilyName"));
    pl.productFamilyId = reader.GetString(reader.GetOrdinal("ProductFamilyId"));
    pl.productFamilyName = reader.GetString(reader.GetOrdinal("ProductFamilyName"));
    productListsDB.Add(pl);
}

Another one is filled with data stored in XLSX file:

for (int rowNum = startingRow; rowNum <= totalRows; rowNum++)
{
    var row = myWorksheet.Cells[rowNum, 1, rowNum, totalColumns].ToArray();

    ProductList pl = new ProductList();
    pl.productSku = (string)row[0].Value;
    pl.productName = (string)row[1].Value;
    pl.productSubfamilyId = (string)row[2].Value;
    pl.productSubfamilyName = (string)row[3].Value;
    pl.productFamilyId = (string)row[4].Value;
    pl.productFamilyName = (string)row[5].Value;
    productListsXLSX.Add(pl);
}

Then I wanted to compare them and:

Assert.IsTrue(Equals(productListsDB.Count,productListsXLSX.Count), "Number of records in Excel file and DB differs!");

Passes just fine!

But any of two following does NOT pass:

Assert.IsTrue(productListsDB.All(productListsXLSX.Contains), "Data sent in Excel file and stored in DB are equal.");
CollectionAssert.AreEquivalent(productListsDB, productListsXLSX, "Data sent in Excel file and stored in DB are equal.");

I'm pretty new to writing and debugging code, but I managed to get some insights of that lists with QuickWatch in VS. I copied data to separate files and compered them - they are identical:

http://pastebin.com/KFDHpQkC and http://pastebin.com/4j1n1nPH

Any clues guys?

Tomek
  • 701
  • 2
  • 8
  • 20

2 Answers2

2

You need to override Equals to tell whether the 2 products are equivalent. Usually when we override Equals, we also override GetHashCode: Why is it important to override GetHashCode when Equals method is overridden?

private class ProductList
{
    public string productSku { get; set; }
    public string productName { get; set; }
    public string productSubfamilyId { get; set; }
    public string productSubfamilyName { get; set; }
    public string productFamilyId { get; set; }
    public string productFamilyName { get; set; }

    public override bool Equals(object otherProduct)
    {
        //your code goes here to tell when the 2 products are equivalent.
        //Here I assume that your 2 products are equal when all the properties are equal:
        if (otherProduct == null)
           return false;
        return this.productSku == otherProduct.productSku &&
               this.productName == otherProduct.productName &&
               this.productSubfamilyId == otherProduct.productSubfamilyId &&
               this.productSubfamilyName == otherProduct.productSubfamilyName &&
               this.productFamilyId == otherProduct.productFamilyId &&
               this.productFamilyName == otherProduct.productFamilyName;
    }

    public override int GetHashCode()
    {
         //return your hash code
         int hash = 13;
         hash = (hash * 7) + this.productSku.GetHashCode();
         hash = (hash * 7) + this.productName.GetHashCode();
         ...
         return hash;
    }
};
Community
  • 1
  • 1
Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • Thanks! Great explanation. Can you please also help me with GetHashCode method? From http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overridden, how should I get "field1" and "field2"? Should I create ProductList object there? – Tomek Oct 24 '15 at 12:55
  • 1
    @BlackHat: See my updated answer. You should not create a ProductList object, just compute it from the current object (`this`) – Khanh TO Oct 24 '15 at 12:58
  • Aren't we overwriting that hash variable there? Shouldn't we += it in next lines? – Tomek Oct 24 '15 at 13:05
  • Overriding Equals just for test purposes is a code smell. Use an equality comparer instead. – Thomas Levesque Oct 24 '15 at 13:09
  • 1
    @BlackHat: we're not overwriting. Using `+=` is also ok – Khanh TO Oct 24 '15 at 13:11
  • @Thomas Levesque: do you have any example of such solution? – Tomek Oct 24 '15 at 13:15
  • @Thomas Levesque: agree. But pragmatically, it does not cause problems, we might need to use this `Equals` some day. – Khanh TO Oct 24 '15 at 13:17
  • @KhanhTO, the problem is not that you don't need the Equals in application code; it is that the equality logic you use in tests is not necessarily the same as in application code. – Thomas Levesque Oct 24 '15 at 13:18
  • @BlackHat, which test framework are you using? MSTests, NUnit ? in MSTests there is a CollectionAssert.AreEqual overload that takes a IComparer, not an IEqualityComparer, but it can work too, just return 0 from the Compare method if the objects are equal. – Thomas Levesque Oct 24 '15 at 13:19
  • @BlackHat, I suggest that you use `Assert.IsTrue(collection1.SequenceEqual(collection2), comparer)` instead of CollectionAssert; it gives you more control. – Thomas Levesque Oct 24 '15 at 13:21
  • @ThomasLevesque It's NUnit used in my project – Tomek Oct 24 '15 at 14:48
1

You have to override the Equals and GetHashCode methods. The Equals method will compare the property of first object to another object property.

user1672994
  • 10,509
  • 1
  • 19
  • 32