Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

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);

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

Leave a Reply