Home > Unit Testing > Extract and Conquer!

Extract and Conquer!

..Or ‘Extract and Override’ as it’s otherwise known

 

I started working on a Dynamics CRM project recently, and a technique I read about in Roy Osherove’s book has started to come in really handy, which he calls ‘Extract and Override’.

Not that it’s specific to CRM, or any particular type of development – indeed, Roy states that he always tries to use this technique first and only defers to other methods of testing if it isn’t possible.  I had certain reservations when I first read about it, but having given it a try over the last few weeks I am now a convert.

The purpose of this technique is to insert a ‘seam’ into your code – a place where you can replace dependencies on other classes & services with fake versions, so you can test one class at a time.  Previously, I’d always done this using constructor injection, whereby you pass the dependencies into the class constructor:

Simple Robot Class

Simple Robot Class

This way, when we want to test the robot mood logic in KillHumans(), we can create fake versions of IWeaponSystem, ICommunication and IMoodManager, and just test the Robot logic.  In the actual system, the real versions of these things would be supplied by a Service Locator/IOC container or similar.

This is all very well, but doesn’t work with CRM because you don’t control creation of classes.  Basically you get passed a service and have to use that for all of your communication with CRM.  To stay with the robot example, it would look something like this:

Robot Class using CRM-Style Service

Robot Class using CRM-Style Service

Because all communication is going through RobotService.Execute(), it’s very difficult to fake this, especially when it’s called multiple times and you need different return values.

To get over this, we can use Extract and Override.  This works by putting the calls to the external services in their own methods, and then overriding them while we’re testing.  This way, we don’t have to create fake services at all!  Just a single fake version of the class we’re testing.  The code in Robot would now look something like this:

Testable Robot Class

Testable Robot Class

Notice that the extra methods are ‘virtual’ so we can override them.  they are also ‘protected’ so they’re accessible from classes which inherit from them.  So now instead of creating fake services, we’d create a testable version of the robot class, like this:

Overriden Robot Class, for Testing

Overriden Robot Class, for Testing

We now have full control over what gets returned from those methods, and we can record when got sent into them.  As such, we can happily test the mood logic in KillHumans() without worrying about those dependencies.

Now, this isn’t limited to the CRM situation described – you can use this technique any time you have a dependency on another service, as an alternative to Dependency Injection.  You can read a bit more about it in one of Roy’s blog posts, which probably explains it a bit better!  Although sadly without the use of robots.

Advertisements
Categories: Unit Testing Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: