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));
}
Objects are not like arrays or strings. So simply comparing by using "===" or "==" is not possible. Here to compare we have to first stringify the object and then using equality operators it is possible to compare the objects.
The referential equality (using === , == or Object.is() ) determines whether the operands are the same object instance. The manual equality check requires a manual comparison of properties' values.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With