views:

36

answers:

1

I am writing tests against our Caching mechanism and I want to be sure that what goes into the cache is the same as what comes out, ie that all properties match. Here is a fictional example of how I would like it to work

    [Test]
    public void add_client_model_member_to_cache_then_retreve()
    {
        //arrange
        MemcachedClient client = new MemcachedClient();
        Member member = GetMember();
        client.Store(StoreMode.Set, "membertest", member);

        // act
        var result = client.Get<Member>("membertest");

        // assert
        Assert.AreMatch(result, member);
    }

It is not feasible to perform Assert.AreEqual on each property as there will be many of these tests with many properties in each.

Wow, thanks Jon. I think you answered that in under one minute. Here are my resulting solution for any interested parties. I implemented as Jon suggested (I think) however I got into a little trouble with array properties and as such my solution only handles arrays of ints (all I currently require).

It also got to be a fairly slippery slope if I try to check deeper than one level. I am sure this can be achieved however for my purposes it is not required.

private bool AreMatch(object initial, object result)
    {
        if (initial.Equals(result)) 
            return true;

        foreach (var property in initial.GetType().GetProperties())
        {
            var initialPropValue = property.GetValue(initial,null);
            var resultPropValue = result.GetType().GetProperty(property.Name).GetValue(result,null);

            if (property.PropertyType.IsArray)
            {
                if ((initialPropValue != null && resultPropValue != null) && !Enumerable.SequenceEqual((int[])initialPropValue, (int[])resultPropValue))
                        return false;                   
            }
            else if (!object.Equals(initialPropValue, resultPropValue))
            {
                return false;
            }
            else if (initialPropValue != null && property.PropertyType.IsClass)
            {
                // Don't go deeper than one level, this got me into trouble
                //if (!AreMatch(initialPropValue, resultPropValue))
                //  return false;
            }
        }
        return true;
    }

The method above can be used in the following situations

    [Test]
    public void cached_result_is_same_as_original()
    {
        //arrange
        Member member = GetMember();
        client.Store(StoreMode.Set, "membertest", member);

        // act
        var result = client.Get<Member>("membertest");

        // assert
        Assert.IsTrue(AreMatch(member, result));
    }

    [Test]
    public void cached_result_is_same_as_original()
    {
        //arrange
        Member member = GetMember();
        client.Store(StoreMode.Set, "membertest", member);

        // act
        var result = client.Get<Member>("membertest");
        result.FirstName = "Result is different"; 

        // assert
        Assert.IsFalse(AreMatch(member, result));
    }
+1  A: 

Well, you could certainly write something to recurse through all the properties, and call object.Equals on the result of fetching the property value from the expected and actual ones. Use Type.GetProperties() to get the properties themselves, and PropertyInfo.GetValue to get the value.

It'll be somewhat crude, but you could always tweak it if necessary.

Jon Skeet