Friday, September 1, 2017

Testing Private Methods

There are times where it is much easier to test a private method instead of the public method. I could agrue this is a not a good idea, but let's assume this is what we want to do.


Option 1: Reflection

You can access anything via Reflection, but it can be a bit difficult to read, particularly for a test. This is probably the hardest to figure out and I would not recommend it.

Option 2: PrivateObject

You can use PrivateObject to invoke the private method in your unit test. 

The syntax would be something like this:

var calculator = new Calculator();
var privateLogic = new PrivateObject(calculator);
privateLogic.Invoke("Add", 1, 1);

To make this easier and more user friendly you could wrap this logic up into a method. A step further you could create an extension method for Calculator in your test project that has an extension method called Add with the same parameters as the private Add method. Then from the test perspective it would act like the private method is public.


Option 3: ReflectionMagic

Another more intuitive option is ReflectionMagic available on Nuget that uses dynamic objects to expose private bits. It can be used as a syntactically easy way to access most anything you can using Reflection. The upside of this is that you don't need to do anything special to access the private method. Unfortunately there is no compiler or Intellisense to help you with the parameters to pass it, but no special coding is needed.

You could use it something like this:

var calculator = new Calculator();
calculator.AsDynamic().Add(1,1);

This is so easy, and requires no special code it probably is not worth writing the wrapper method as I talked about the the PrivateObject option.

NOTE: I had mixed results with ReflectionMagic, but the same raw source code did work.

No comments: