Click here to Skip to main content
15,886,545 members
Articles / Entity Framework
Technical Blog

Mocking the Unmockable: Using Microsoft Moles with Gallio

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
31 Jul 2010CPOL6 min read 11.2K   1   1
CodeProjectUpdate 29/04/10: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...

Update 29/04/10:

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...


 

Usual opensource mocking frameworks (like e.g. Moq or Rhino.Mocks) can mock only interfaces and virtual methods. In contrary to that, Microsoft’s Moles framework can ‘mock’ virtually anything, in that it uses runtime instrumentation to inject callbacks in the method MSIL bodies of the moled methods. Therefore, it is possible to detour any .NET method, including non-virtual/static methods in sealed types. This can be extremely helpful when dealing e.g. with code that calls into the .NET framework, some third-party or legacy stuff etc…

Some useful collected resources (links to website, documentation material and some videos) can be found in my toolbox on Delicious under this link:

http://delicious.com/thomasweller/toolbox+moles

A Gallio extension for Moles

Originally, Moles is a part of Microsoft’s Pex framework and thus integrates best with Visual Studio Unit Tests (MSTest). However, the Moles sample download contains some additional assemblies to also support other unit test frameworks. They provide a Moled attribute to ease the usage of mole types with the respective framework (there are extensions for NUnit, xUnit.net and MbUnit v2 included with the samples). As there is no such extension for the Gallio platform, I did the few required lines myself – the resulting Gallio.Moles.dll is included with the sample download.

With this little assembly in place, it is possible to use Moles with Gallio like that:

[<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> SomeTest()
{
    ...

What you can do with it

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:

[<span style="color: blue;">assembly</span>: <span style="color: rgb(43, 145, 175);">MoledType</span>(<span style="color: blue;">typeof</span>(System.IO.<span style="color: rgb(43, 145, 175);">File</span>))]

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;">// arrange ('mock' the FileSystem with a delegate)</span>
        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;">// act </span>
        <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;">// assert </span>
        <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…

     

    kickit
    shoutit
    <iframe width="150" height="20" frameborder="0" scrolling="no" style="position: relative; top: 4px;" id="dzoneframe" title="Zone it!" src="http://widgets.dzone.com/links/widgets/zoneit.html?t=2&url=&title="></iframe>
    delicious facebook digg reddit linkedin stumbleupon technorati mrwong yahoo google-48x48 twitter email favorites

 

<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> </noscript> </iframe>

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Freelancer
Germany Germany
I'm a freelance software developer/architect located in Southern Germany with 20 years of experience in C++, VB, and C# software projects. Since about ten years I do all my coding exclusively in C# for business application development - and nowadays Python for Data Science, ML, and AI.
I am especially dedicated to Test-driven development, OO architecture, software quality assurance issues and tools.

Comments and Discussions

 
GeneralLooks good but... Pin
Sandeep Mewara31-Jul-10 23:37
mveSandeep Mewara31-Jul-10 23:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.