Unit Testing Private Setter Question (C#)

Since you are checking the behavior of your Order you can use mock objects as its items. Using mock objects you can define your assertions of what's going to happen to your mock objects and test them too. In this case you can define two mock objects for each of items and expect that their id getter will be called and will return a unique value.Then you can test the Order behavior and check to see if id getter of item is called as you expected. I recommend using Rhino Mocks by Ayende


While Praveen's answer is correct and without doubt serves for the single usage, it misses some type safety to use this in tests over a strong domain model over and over. Therefore I wrapped it in an extension method that allows you this type safe call to set a value:

var classWithPrivateSetters= new ClassWithPrivateSetters();
classWithPrivateSetters.SetPrivate(cwps => cwps.Number, 42);

Drop this into your test assembly and you are good to go

public static class PrivateSetterCaller
{
    public static void SetPrivate<T,TValue>(this T instance, Expression<Func<T,TValue>> propertyExpression, TValue value)
    {
        instance.GetType().GetProperty(GetName(propertyExpression)).SetValue(instance, value, null);
    }

    private static string GetName<T, TValue>(Expression<Func<T, TValue>> exp)
    {
        MemberExpression body = exp.Body as MemberExpression;

        if (body == null)
        {
            UnaryExpression ubody = (UnaryExpression)exp.Body;
            body = ubody.Operand as MemberExpression;
        }

        return body.Member.Name;
    }
}

I usually use reflection for this purpose. Something like this will work:

typeof(Item).GetProperty(nameof(Item.Id)).SetValue(i, 1, null);

where 1 is the id that you want to set for the newItem instance.

In my experience, you'll rarely need to set the Id, so it's better just to leave the setter private. In the few cases that you do need to set the Id for testing purposes, simply use Reflection.