In contrary to what I initially stated in this post, Moles is not only available as part of the Pex framework, but also stand-alone on Visual Studio Gallery, and this is completely free (no MSDN subscription required). - Thanks to Peli for the correction...
Some useful collected resources (links to website, documentation material and some videos) can be found in my toolbox on Delicious under this link:
With this little assembly in place, it is possible to use Moles with Gallio like that:
Moles can be very helpful, if you need to ‘mock’ something other than a virtual or interface-implementing method. This might be the case when dealing with some third-party component, legacy code, or if you want to ‘mock’ the .NET framework itself.
Generally, you need to announce each moled type that you want to use in a test with the MoledType attribute on assembly level. For example:
Below are some typical use cases for Moles. For a more detailed overview (incl. naming conventions and an instruction on how to create the required moles assemblies), please refer to the reference material above.
Detouring the .NET framework
Imagine that you want to test a method similar to the one below, which internally calls some framework method:
<span style="color: blue;">public</span> <span style="color: blue;">void</span> ReadFileContent(<span style="color: blue;">string</span> fileName)
{
<span style="color: blue;">this</span>.FileContent = System.IO.<span style="color: rgb(43, 145, 175);">File</span>.ReadAllText(fileName);
}
Using a mole, you would replace the call to the File.ReadAllText(string) method with a runtime delegate like so:
[<span style="color: rgb(43, 145, 175);">Test</span>, <span style="color: rgb(43, 145, 175);">Moled</span>]
[<span style="color: rgb(43, 145, 175);">Description</span>(<span style="color: rgb(163, 21, 21);">"This 'mocks' the System.IO.File class with a custom delegate."</span>)]
<span style="color: blue;">public</span> <span style="color: blue;">void</span> ReadFileContentWithMoles()
{
<span style="color: green;">
System.IO.Moles.<span style="color: rgb(43, 145, 175);">MFile</span>.ReadAllTextString =
(fname => fname == FileName ? FileContent : <span style="color: rgb(163, 21, 21);">"WrongFileName"</span>);
<span style="color: green;">
<span style="color: blue;">var</span> testTarget = <span style="color: blue;">new</span> TestTarget.<span style="color: rgb(43, 145, 175);">TestTarget</span>();
testTarget.ReadFileContent(FileName);
<span style="color: green;">
<span style="color: rgb(43, 145, 175);">Assert</span>.AreEqual(FileContent, testTarget.FileContent);
}
Detouring static methods and/or classes
A static method like the below…
<span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">string</span> StaticMethod(<span style="color: blue;">int</span> x, <span style="color: blue;">int</span> y)
{
<span style="color: blue;">return</span> <span style="color: blue;">string</span>.Format(<span style="color: rgb(163, 21, 21);">"{0}{1}"</span>, x, y);
}
… can be ‘mocked’ with the following:
[<span style="color: rgb(43, 145, 175);">Test</span>, <span style="color: rgb(43, 145, 175);">Moled</span>]
<span style="color: blue;">public</span> <span style="color: blue;">void</span> StaticMethodWithMoles()
{
<span style="color: rgb(43, 145, 175);">MStaticClass</span>.StaticMethodInt32Int32 = ((x, y) => <span style="color: rgb(163, 21, 21);">"uups"</span>);
<span style="color: blue;">var</span> result = <span style="color: rgb(43, 145, 175);">StaticClass</span>.StaticMethod(1, 2);
<span style="color: rgb(43, 145, 175);">Assert</span>.AreEqual(<span style="color: rgb(163, 21, 21);">"uups"</span>, result);
}
Detouring constructors
You can do this delegate thing even with a class’ constructor. The syntax for this is not all too intuitive, because you have to setup the internal state of the mole, but generally it works like a charm. For example, to replace this c’tor…
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">ClassWithCtor</span>
{
<span style="color: blue;">public</span> <span style="color: blue;">int</span> Value { <span style="color: blue;">get</span>; <span style="color: blue;">private</span> <span style="color: blue;">set</span>; }
<span style="color: blue;">public</span> ClassWithCtor(<span style="color: blue;">int</span> someValue)
{
<span style="color: blue;">this</span>.Value = someValue;
}
}
… you would do the following:
[<span style="color: rgb(43, 145, 175);">Test</span>, <span style="color: rgb(43, 145, 175);">Moled</span>]
<span style="color: blue;">public</span> <span style="color: blue;">void</span> ConstructorTestWithMoles()
{
<span style="color: rgb(43, 145, 175);">MClassWithCtor</span>.ConstructorInt32 =
((@class, @value) => <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">MClassWithCtor</span>(@class) {ValueGet = () => 99});
<span style="color: blue;">var</span> classWithCtor = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">ClassWithCtor</span>(3);
<span style="color: rgb(43, 145, 175);">Assert</span>.AreEqual(99, classWithCtor.Value);
}
Detouring abstract base classes
You can also use this approach to ‘mock’ abstract base classes of a class that you call in your test. Assumed that you have something like that:
<span style="color: blue;">public</span> <span style="color: blue;">abstract</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">AbstractBaseClass</span>
{
<span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">string</span> SaySomething()
{
<span style="color: blue;">return</span> <span style="color: rgb(163, 21, 21);">"Hello from base."</span>;
}
}
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">ChildClass</span> : <span style="color: rgb(43, 145, 175);">AbstractBaseClass</span>
{
<span style="color: blue;">public</span> <span style="color: blue;">override</span> <span style="color: blue;">string</span> SaySomething()
{
<span style="color: blue;">return</span> <span style="color: blue;">string</span>.Format(
<span style="color: rgb(163, 21, 21);">"Hello from child. Base says: '{0}'"</span>,
<span style="color: blue;">base</span>.SaySomething());
}
}
Then you would set up the child’s underlying base class like this:
[<span style="color: rgb(43, 145, 175);">Test</span>, <span style="color: rgb(43, 145, 175);">Moled</span>]
<span style="color: blue;">public</span> <span style="color: blue;">void</span> AbstractBaseClassTestWithMoles()
{
<span style="color: rgb(43, 145, 175);">ChildClass</span> child = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">ChildClass</span>();
<span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">MAbstractBaseClass</span>(child)
{
SaySomething = () => <span style="color: rgb(163, 21, 21);">"Leave me alone!"</span>
}
.InstanceBehavior = <span style="color: rgb(43, 145, 175);">MoleBehaviors</span>.Fallthrough;
<span style="color: blue;">var</span> hello = child.SaySomething();
<span style="color: rgb(43, 145, 175);">Assert</span>.AreEqual(<span style="color: rgb(163, 21, 21);">"Hello from child. Base says: 'Leave me alone!'"</span>, hello);
}
Setting the moles behavior to a value of MoleBehaviors.Fallthrough causes the ‘original’ method to be called if a respective delegate is not provided explicitly – here it causes the ChildClass’ override of the SaySomething() method to be called.
There are some more possible scenarios, where the Moles framework could be of much help (e.g. it’s also possible to detour interface implementations like IEnumerable<T> and such…). One other possibility that comes to my mind (because I’m currently dealing with that), is to replace calls from repository classes to the ADO.NET Entity Framework O/R mapper with delegates to isolate the repository classes from the underlying database, which otherwise would not be possible…
Usage
Since Moles relies on runtime instrumentation, mole types must be run under the Pex profiler. This only works from inside Visual Studio if you write your tests with MSTest (Visual Studio Unit Test). While other unit test frameworks generally can be used with Moles, they require the respective tests to be run via command line, executed through the moles.runner.exe tool. A typical test execution would be similar to this:
moles.runner.exe <mytests.dll> /runner:<myframework.console.exe> /args:/<myargs>
So, the moled test can be run through tools like NCover or a scripting tool like MSBuild (which makes them easy to run in a Continuous Integration environment), but they are somewhat unhandy to run in the usual TDD workflow (which I described in some detail here). To make this a bit more fluent, I wrote a ReSharper live template to generate the respective command line for the test (it is also included in the sample download – moled_cmd.xml). - This is just a quick-and-dirty ‘solution’. Maybe it makes sense to write an extra Gallio adapter plugin (similar to the many others that are already provided) and include it with the Gallio download package, if there’s sufficient demand for it.
As of now, the only way to run tests with the Moles framework from within Visual Studio is by using them with MSTest. From the command line, anything with a managed console runner can be used (provided that the appropriate extension is in place)…
A typical Gallio/Moles command line (as generated by the mentioned R#-template) looks like that:
"%ProgramFiles%\Microsoft Moles\bin\moles.runner.exe" /runner:"%ProgramFiles%\Gallio\bin\Gallio.Echo.exe" "Gallio.Moles.Demo.dll" /args:/r:IsolatedAppDomain /args:/filter:"ExactType:TestFixture and Member:ReadFileContentWithMoles"
-- Note: When using the command line with Echo (Gallio’s console runner), be sure to always include the IsolatedAppDomain option, otherwise the tests won’t use the instrumentation callbacks! --
License issues
As I already said, the free mocking frameworks can mock only interfaces and virtual methods. if you want to mock other things, you need the Typemock Isolator tool for that, which comes with license costs (Although these ‘costs’ are ridiculously low compared to the value that such a tool can bring to a software project, spending money often is a considerable gateway hurdle in real life...). The Moles framework also is not totally free, but comes with the same license conditions as the (closely related) Pex framework: It is free for academic/non-commercial use only, to use it in a ‘real’ software project requires an MSDN Subscription (from VS2010pro on).
The demo solution
The sample solution (VS 2008) can be downloaded from here. It contains the Gallio.Moles.dll which provides the here described Moled attribute, the above mentioned R#-template (moled_cmd.xml) and a test fixture containing the above described use case scenarios. To run it, you need the Gallio framework (download) and Microsoft Moles (download) being installed in the default locations.
Happy testing…
<iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&Task=Get&PageID=31016&SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No>
<script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&Task=Get&Browser=NETSCAPE4&NoCache=True&PageID=31016&SiteID=1"></script>
<noscript>