Thursday, July 28, 2011

Simple Test Utils

When I'm writing tests, I prefer not to use a mock/stub/fake library until simpler methods become painful. Here are two functions I find myself using in many of my tests to break encapsulation and arrange the test.

Set a property with a private setter

public static void SetProperty<T, V>(this T obj,
    Expression<Func<T, V>> expression, V value)
{
    var body = expression.Body as MemberExpression;
    if (body == null)
    {
        throw new Exception("expression.Body must be a Property");
    }

    var property = body.Member as PropertyInfo;
    if (property == null)
    {
        throw new Exception("expression.Body must be a Property");
    }

    property.SetValue(obj, value, null);
}
Usage:
var entity = new SomeEntity();
entity.SetProperty(me => me.Id, 123);
I like the Intellisense support when choosing the property, and I especially like the type safety here – passing "a string" to an integer property is a compile-time error.

Instantiate an object with no public constructor

public static T Instantiate<T>() where T : class
{
    return System.Runtime.Serialization.FormatterServices
        .GetUninitializedObject(typeof(T)) as T;
}
Usage:
var entity = Instantiate<SomeEntity>();
This one you have to be a little more careful with. It will not call any of the constructors of the class. If you just want an object to exist, this method is fine. If you want an object to exist in a certain state, then you may want to use reflection to call a specific constructor. Relying on the existence and behavior of a particular constructor is more brittle than GetUninitializedObject with regard to mere instantiation. With regard to initialization, it depends on the type of object being created, and what you need from that object. For example, if all you're going to do is call object.GetType(), then it doesn't matter if the object was properly initialized.