In any unit testing activity, there always comes a point when one needs to isolate the code under test from the environment. This usually involves adding interfaces at the environment boundaries, which can be used to test the code in isolation. Because implementing those interfaces ‘by hand’ for the test can be tedious, an ecosystem of mock frameworks has flourished (NMock, Rhino Mocks, Moq, there’s more…). In fact, it’s a pretty competitive area.
The dark side of Mocks frameworks
Under their friendly API, mock frameworks usually hide a complex machinery: dynamic code (through Reflection.Emit or a rewriting profiler), expression trees or reflection.
From a Pex point of view, this ‘machinery’ puts a large burden on the dynamic whitebox code analysis; Pex does a precise data flow and control analysis for any code that is executed, this means that it also has to analyze the mock infrastructure.
Therefore, we decided to build a framework to define stubs that would try to avoid the overhead of dynamic code generation (just rely on source code) and still provide the same level of flexibility of existing mock frameworks: defining the behavior of the stub inside the test, strongly typed, intellisense support, first-class debugging experience, etc…
Low tech Stubs using delegates
With C# 3.0 lambdas, it is quite easy to define delegates. Therefore, delegates seemed an elegant and simple way for building stub methods (we’re not the first ones to think about this). For example, a stub of the IServiceProvider would simply be
class SServiceProvider : IServiceProvider { // this field can be set to ‘override’ the behavior of GetService public Func GetServiceHandler; object IServiceProvider.GetService(Type type) { var d = this.GetServiceHandler; if (d != null) return d(type); // i’m stubbed :) else throw new NotImplementedException(); }}
Enter the Stubs framework
We took this simple idea and turned it into the Stubs framework. The Stubs framework comes as a enhanced single file generator for Visual Studio which generates stubs for selected assemblies. Special attention was paid to make sure the code generation did not get into the feet for the unit test writer (we track the build events and regenerate when needed).
More about stubs can be found at http://research.microsoft.com/pex/articles/stubs.pdf. This is a preview of what’s coming up on the next release of Pex at the end of the month.
Happy stubbing.
Page rendered at Wednesday, January 07, 2009 6:16:24 AM UTC
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.