A bit of reflection may help…

when unit tests call legacy code.

It can be tricky adding unit tests to your code if it calls legacy code that can’t be changed for one reason or other. In some cases, it might be possible to use reflection to your advantage.

Under consideration today are cases where the call to the legacy code can be intercepted by instantiating a private/internal variable, instance or static, which is usually checked before calling a service/database etc.

The library Fasterflect is being used in the following examples, but the same can be achieved by using other such libraries or indeed crafting the reflection code on your own.

Please be advised that what’s being proposed should be taken as an interim stage to the final solution – removal of such dependencies. Using reflection or tools like TypeMock as a norm is likely to lead to poor, tightly coupled design.

Instance private variable:

private IList _assets;
public Asset GetAsset(int id)
   {
       if (this._assets == null || this._assets.Count == 0)
       {
           // Call to avoid for unit testing
           this._assets = new AssetService().GetAll();
       }
       return this._assets.FirstOrDefault(x => x.Id == id);
   }
If the AssetService call above is something we want to avoid  for unit testing, and obviously we are not in a position to modify the above code, the following code will do the needful:
 this._manager = new AssetManager();
 this._manager.SetFieldValue("_assets", this._assets);
Now any tests that need the variable can be called without the offending call. Examples given in AssetManageFixture.cs class here.

Static private variable:

 private static ServiceProxy _instance;
 public static ServiceProxy Instance
    {
        get
        {
            return _instance ??
            (_instance = new ServiceProxy
                   {
                       ServiceAdapter = new ProductionService(),
                   }
            );
        }
    }
 internal ProductionService ServiceAdapter;
In this case, to fill the static variable, the code is slightly different:
 var type = typeof (ServiceProxy);
 type.SetFieldValue("_instance", _serviceProxy.Object);
The full working example is provided in UrlHelperFixture.cs class at link provided below.
In a similar vein other internal variables or methods can be used/called to allow unit testing for code that calls inaccessible legacy code.

The test files mentioned above can be viewed as part of the Github site for the sample class library.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s