views:

71

answers:

3

Hi all,

In a Unit Test (in Visual Studio 2008) I want to compare the content of a large object (a list of custom types, to be precise) with a stored reference of this object. The goal is to make sure, that any later refactorings of the code produces the same object content.

Discarded Idea: A first thought was to serialize to XML, and then compare the hardcoded strings or a file content. This would allow for easy finding of any difference. However since my types are not XML serializable without a hack, I must find another solution. I could use binary serialization but this will not be readable anymore.

Is there a simple and elegant solution to this?

EDIT: According to Marc Gravell's proposal I do now like this:

using (MemoryStream stream = new MemoryStream())
        {
            //create actual graph using only comparable properties
            List<NavigationResult> comparableActual = (from item in sparsed
                                                       select new NavigationResult
                                                       {
                                                           Direction = item.Direction,
                                                           /*...*/
                                                           VersionIndication = item.VersionIndication
                                                       }).ToList();

            (new BinaryFormatter()).Serialize(stream, comparableActual);
            string base64encodedActual = System.Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length);//base64 encoded binary representation of this                
            string base64encodedReference = @"AAEAAAD....";//this reference is the expected value
            Assert.AreEqual(base64encodedReference, base64encodedActual, "The comparable part of the sparsed set is not equal to the reference.");
        }

In essence I do select the comparable properties first, then encode the graph, then compare it to a similarly encoded reference. Encoding enables deep comparison in a simple way. The reason I use base64 encoding is, that I can easily store the reference it in a string variable.

+5  A: 

I would still be inclined to use serialization. But rather than having to know the binary, just create an expected graph, serialize that. Now serialize the actual graph and compare bytes. This is only useful to tell you that there is a difference; you'd need inspection to find what, which is a pain.

Marc Gravell
Yeah, I'm currently doing this like you say, but I want to avoid the pain!
Marcel
So now, still do I feel the pain, but my test now works with the edit in the question, doing it like you proposed.
Marcel
Maybe a combination of binary serialization and deep reflection analysis (as in my idea) in case of mismatch in binary comparision will solve it.
Migol
+1  A: 

I would use the hack to do XML comparision. Or you could use reflection to automaticaly traverse object properties (but this will traverse ALL of them, also some you could not want to).

Migol
Unfortunately the hack is, to manipulate a generated file (generated by the entity framework)
Marcel
Isn't entity framework generated classes partial? Can't you apply the "hack" in another file extending the partial classes as needed?If you are using VS2010 it also includes ADO.NET EntityObject Generator template. Then you can actually modify Entity Objects template to match your requirements.
FuleSnabel
+1  A: 

I would make each custom type inherit IComparable, and provide equality methods, that compare each custom types, as well as making the main class ICompareble, You can then simply compare the 2 objects ( if you have them in memory when running unit tests) If not then I would suggest either serializing, or defining constants which you expect the refactored object to have.

LnDCobra
Well, it's a nice solution too as it add some functionality to classes at cost of writing code and possible leaks (if some object don't provide IComparable, then it will NOT be reliable).
Migol