Geeks With Blogs
// ThomasWeller C#/.NET software development, software integrity, life as a freelancer, and all the rest

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:

[Test, Moled]
public void 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:

[assembly: MoledType(typeof(System.IO.File))]

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: 

    public void ReadFileContent(string fileName)
    {
        this.FileContent = System.IO.File.ReadAllText(fileName);
    }

    Using a mole, you would replace the call to the File.ReadAllText(string) method with a runtime delegate like so:

    [Test, Moled]
    [Description("This 'mocks' the System.IO.File class with a custom delegate.")]
    public void ReadFileContentWithMoles()
    {
        // arrange ('mock' the FileSystem with a delegate)
        System.IO.Moles.MFile.ReadAllTextString = 
            (fname => fname == FileName ? FileContent : "WrongFileName");
     
        // act 
        var testTarget = new TestTarget.TestTarget();
        testTarget.ReadFileContent(FileName);
     
        // assert 
        Assert.AreEqual(FileContent, testTarget.FileContent);
    }

     

    Detouring static methods and/or classes

    A static method like the below…

    public static string StaticMethod(int x, int y)
    {
        return string.Format("{0}{1}", x, y);
    }

    … can be ‘mocked’ with the following:

    [Test, Moled]
    public void StaticMethodWithMoles()
    {
        MStaticClass.StaticMethodInt32Int32 = ((x, y) => "uups");
     
        var result = StaticClass.StaticMethod(1, 2);
     
        Assert.AreEqual("uups", 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…

    public class ClassWithCtor
    {
        public int Value { get; private set; }
     
        public ClassWithCtor(int someValue)
        {
            this.Value = someValue;
        }
    }

    … you would do the following:

    [Test, Moled]
    public void ConstructorTestWithMoles()
    {
        MClassWithCtor.ConstructorInt32 =
               ((@class, @value) => new MClassWithCtor(@class) {ValueGet = () => 99});
     
        var classWithCtor = new ClassWithCtor(3);
     
        Assert.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:

    public abstract class AbstractBaseClass
    {
        public virtual string SaySomething()
        {
            return "Hello from base.";
        }
    }  
     
    public class ChildClass : AbstractBaseClass
    {
        public override string SaySomething()
        {
            return string.Format(
                "Hello from child. Base says: '{0}'", 
                base.SaySomething());
        }
    }

    Then you would set up the child’s underlying base class like this:

    [Test, Moled]
    public void AbstractBaseClassTestWithMoles()
    {
        ChildClass child = new ChildClass();
        new MAbstractBaseClass(child)
            {
                    SaySomething = () => "Leave me alone!"
            }
            .InstanceBehavior = MoleBehaviors.Fallthrough;
     
        var hello = child.SaySomething();
     
        Assert.AreEqual("Hello from child. Base says: 'Leave me alone!'", 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
    delicious facebook digg reddit linkedin stumbleupon technorati mrwong yahoo google-48x48 twitter email favorites

 

Posted on Wednesday, April 28, 2010 1:36 PM Unit Testing/TDD , Automation | Back to top


Comments on this post: Mocking the Unmockable: Using Microsoft Moles with Gallio

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
Excellent post, 1 correction:

Moles is freely available on Visual Studio gallery at http://visualstudiogallery.msdn.microsoft.com/en-us/b3b41648-1c21-471f-a2b0-f76d8fb932ee. No MSDN suscription needed.
Left by Peli on Apr 29, 2010 4:38 PM

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
Hi Peli,

thanks for the correction. Didn't know that, because I heard of Moles only as a part of Pex until now.

I will update this post accordingly.

- Thomas
Left by Thomas Weller on Apr 29, 2010 4:53 PM

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
informative post ,thanks
Left by quran learning on May 01, 2010 11:52 PM

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
I will download Moles from the web adress you gave and try to understand the information you gave in article.
Left by Kale Kapı on Feb 22, 2011 7:33 PM

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
I have downlaoded and testet. The Moles works great
Left by Cem kara on May 23, 2011 4:29 PM

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
well i tried on my pc like it got stuck don't know why
Left by learn quran on Feb 11, 2012 9:14 PM

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
it's looking very useful post
Left by learn quran on Mar 18, 2013 2:29 AM

# Thanks!
Requesting Gravatar...
Thanks for posting this. Your blog is so interesting and very informative.Thanks sharing. Definitely a great piece of work Thanks for your work.

Left by Ali Khan on May 08, 2013 7:05 AM

# Wow
Requesting Gravatar...
Thanks for posting this. Your blog is so interesting and very informative.Thanks sharing. Definitely a great piece of work Thanks for your work.
Left by Remy Hair on May 08, 2013 11:44 AM

# re: Mocking the Unmockable: Using Microsoft Moles with Gallio
Requesting Gravatar...
I really appreciate the information you have provided in this article. Thanks a lot! Very nice! Social Club Insurance
Left by Club Insurance on Jan 08, 2014 4:58 PM

Your comment:
 (will show your gravatar)
 


Copyright © Thomas Weller | Powered by: GeeksWithBlogs.net | Join free