Steve Hebert's Development Blog

Sponsors

The Lounge

Currently Reading

My Amazon Wish List

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Old Code, New Testing Tricks - breaking old habits

I ran into a variation on an old threading problem the other day that I found nearly impossible to unit test.  When I say impossible, getting my test scenario to succeed meant the guaranteed setting of two threading primitives before a WaitHandle evaluation occurred.  Getting this to run properly every time requires some fancy test code which is where I stop and say to myself - "there has to be a better approach."

The resolution is extremely simple, but in a solution I've coded up many times in different situations, it takes a little more thought to break old habits and get it right.  It's that 'ah-ha' moment that made this enjoyable. 

Getting to the Testability Problem...

The problem itself is specific to a threading situation - and it occurs when combining the fact that you can't just throw an unhandled exception from a thread and you want to give precedence to the abort event.  In the case where both the work and abort events below are signaled prior to the .WaitAny() call being evaluated, the AbandonedWorkItemException must be raised to let the client know that the target work item was not handled.

BadCode

As you can see, this makes testing line #29 extremely difficult.

Stepping Back for Minute...

So I sat back, went back to the basics and asked myself - what is this class' responsibility?  The answer was simple - maintain thread state and synchronize thread access.  The 'and' points out the problem - one of these responsibilities needs to be refactored. As I mentioned earlier, the solution is quite simple - I first refactored the threading work into another class and then extracted the members to an interface to support injection. The interface looks like this:

interface

This results in a much more readable ThreadProc function as shown below.

GoodCode

Turning attention back to the ThreadProc function, the old line #29 becomes line #25 in the new code, and it is now easily tested with a mocking class or I can simply code up my interface mock expectations with something like RhinoMocks using:

Expect.Call(synchHandler.ExecuteWorkerItem).Return(false);
Expect.Call(synchHandler.WorkerEventSignaled).Return(true);


Posted Wed, Oct 8 2008 8:59 AM by shebert

[Advertisement]

Comments

Reflective Perspective - Chris Alcock » The Morning Brew #197 wrote Reflective Perspective - Chris Alcock » The Morning Brew #197
on Thu, Oct 9 2008 3:19 AM

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #197

Dew Drop - October 9, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - October 9, 2008 | Alvin Ashcraft's Morning Dew
on Thu, Oct 9 2008 9:57 AM

Pingback from  Dew Drop - October 9, 2008 | Alvin Ashcraft's Morning Dew

Dew Drop - October 9, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - October 9, 2008 | Alvin Ashcraft's Morning Dew
on Sun, Oct 12 2008 6:01 PM

Pingback from  Dew Drop - October 9, 2008 | Alvin Ashcraft's Morning Dew