Calling private methods and properties in unit tests with PrivateObject

Sometimes you have to write a unit test that has to set a private property or call a private method of an object. When applying DDD, property setters can be made private. Off course you can set them public in some cases, but most of the time there will be a good reason for using private properties or methods and if you are using some external library you simply can’t change the accessibility of the class members.

The most used option I saw in previous projects is to use reflection to call private members. But why should you reinvent the wheel? Since Visual Studio 2005, Microsoft provided us with the PrivateObject class. This class also uses reflection to manipulate private members and has a very simple syntax.

An instance of PrivateObject wraps a ‘normal’ object and exposes some interesting methods:

  • GetField, GetProperty and GetFieldOrProperty provides the value of the private field or property.
  • SetField, SetProperty and SetFieldOrProperty are used to set these values.
  • The different overloads of the  Invoke method allow to call private methods.

As an example I created a simple Calculator class, which  encapsulates a private field _memory. Setting and getting the value of the _memory field by making use of PrivateObject is shown in the following code.

         [TestMethod]
        public void TestCalculatorMemory()
        {
            var calculator = new Calculator();
            var privateCalculator = new PrivateObject(calculator);
            privateCalculator.SetField("_memory", 2);

            Assert.AreEqual(2, privateCalculator.GetField("_memory"));
        }