Assert.IsEqualGraph(object a, object b)

Security Briefs

Syndication

Here's some handy unit testing code I put together to traverse two object graphs and assert that they are the same (at least their public properties). I didn't see anything like this in NUnit, and I wanted something like this to test the output of a web service. Seems to work OK so far.

I'm sure I'm not the first to build this, but I imagine someone might find it useful. Note this doesn't look for fields, only properties, but you could easily extend it if you needed to.

public void AssertGraphPropertiesEqual(object expected, object actual)
{
    AssertGraphPropertiesEqual(expected, actual, null);
}
public void AssertGraphPropertiesEqual(object expected, object actual, string parentDescription)
{
    if (null == expected || null == actual)
    {
        Assert.AreEqual(expected, actual, parentDescription);
        return;
    }
    Assert.AreSame(expected.GetType(), actual.GetType());
    Type t = expected.GetType();
    foreach (PropertyInfo pi in t.GetProperties())
    {
        object e = pi.GetValue(expected, null);
        object a = pi.GetValue(actual, null);
        string propertyDescription = (null == parentDescription)
            ? pi.Name : string.Format("{0}.{1}", parentDescription, pi.Name);
        if (pi.PropertyType.IsValueType || typeof(string) == pi.PropertyType)
        {
            Assert.AreEqual(e, a,
                string.Format("Expected {0} but got {1} for property {2}",
                e, a, propertyDescription));
        }
        else if (pi.PropertyType.IsAssignableFrom(typeof(IEnumerable)))
        {
            // some sort of list/array that we need to drill into
            IEnumerator it_e = ((IEnumerable)e).GetEnumerator();
            IEnumerator it_a = ((IEnumerable)a).GetEnumerator();
            int count = 0;
            while (true)
            {
                if (it_e.MoveNext())
                {
                    ++count;
                    Assert.IsTrue(it_a.MoveNext(), string.Format(
                        "Expected more items: actual {0} only has {1} items",
                        propertyDescription, count));
                    AssertGraphPropertiesEqual(it_e.Current, it_a.Current,
                        string.Format("{0}[{1}]", propertyDescription, count - 1));
                }
                else
                {
                    Assert.IsFalse(it_a.MoveNext(),
                        string.Format("Expected {0} items in collection {1}, " +
                        "but actual has more than that",
                        count, propertyDescription));
                    return; // all done enumerating
                }
            }
        }
        else
        {
            // just some random object - compare its properties
            AssertGraphPropertiesEqual(e, a, propertyDescription);
        }
    }
}

Posted Jun 01 2005, 04:31 PM by keith-brown
Filed under:

Comments

qwe wrote qwe
on 06-07-2005 5:16 AM
qwe
Geek Noise wrote Geek Notes 2005-07-17
on 07-18-2005 10:20 PM
abc wrote Try this as well
on 01-15-2008 5:46 AM
http://www.codeproject.com/KB/dotnet/assertpublicpropertieseq.aspx