Getting Started With Moles
Microsoft Moles seems pretty cool, so I’ve decided to set it up and play with it. However, because it’s a research project, the documentation isn’t exactly thorough. I found some videos and various tutorials but nevertheless had a lot of digging in order to get it working. I’m going to document some of the hurdles here for posterity and for myself, in case I need to do this again.
Installation
First off, I’ve been using Pex for a while now, so I just assumed that I’d have Moles installed. It appeared as though this wasn’t the case when I watched a Moles startup video. You see, I didn’t have the template that he references in the video, and I got no joy from doing “devenv /installvstemplates” (which, by the way, is very handy if you find that you’re missing some template that should be installed for whatever reason). As it turns out, the reason I don’t have it is because it’s apparently now deprecated and not the way things are done. I didn’t find this out until after I had un-installed and re-installed Pex and Moles, so I don’t know whether or not Moles was originally functioning with Pex. Probably, but who knows?
Getting Started
After that, I browsed a few posts like this one and saw that the thing I should be going for is getting these M types up and recognized by Intellisense. For instance, I want to test a class that’s using the System.IO.Directory class, so what I want is “MDirectory” for creating Moles. I got the sense that the thing to do here was to right-click on the library reference in question (i.e. “System”) and add a Moles assembly. This is wrong. Very wrong. I got about 25 compiler errors after I tried to build.
By trial and error (read: luck), I discovered that you want to right-click on “References” in your test project and “Add Moles Assembly For mscorlib.”
Type was not instrumented…huh?
Once I’d gotten my M types in place, I was set to go. So I coded up a test that should pass if I implemented the delegate logic correctly, and I ran it. At this time, I got an exception in the test run. In opening the test result details, the Moles team was actually helpful enough to include this comment in the results:
“To resolve this issue, add the following attribute in the test project:
using Microsoft.Moles.Framework;
[assembly: MoledType(typeof(System.IO.Directory))]”
That’s pretty helpful. So, okie-dokie…and, viola! It passed.
Actual Use
If you understand functions and delegates, there’s not a lot to actual use. Once I’d gotten the annoyances out of the way, using this was actually very easy, and I found it to be quite powerful.
One thing I noticed is that it does introduce a bit of overhead when you start your test run. I’m keeping my eye on this to see if it’s a one-time, up-front cost, or if it scales and causes your test runs to be slower as you use it more.
Moling your own classes
This was fairly straightforward if you’re moling your public classes. You just right-click on your project under test in the test project’s references and select “Add Moles Assembly.” It gets a little more interesting if you want to mole internal classes.
To do this, open up the AssemblyInfo.cs class of your project under test and add an [assembly: InternalsVisibleTo(“{YourProjectNamespace}.Moles”)]. In order to know exactly what to add, just mimic the new reference that appears in your test project after you add a new moles assembly.
Moling constructors
For most instance based methods, the declaration looks something like:
MStreamReader.AllInstances.ReadToEnd = (o) => { return @"C:\ and some other stuff"; };
That is, you’ll get pretty used to the “AllInstances,” it appears. But one gotcha is that you mole a constructor like this:
MStreamReader.ConstructorString = (sr, s) => { };
That’s not really that big of a gotcha, but I’m just kind of documenting here all the things that I had to go poking around to figure out.