Moles – isolate your test unit

2010/03/25

no comments

Moles,Test,UnitTest,Pex Moles – isolate your test unit

 

this post will focus on the Moles – Isolation framework for .NET.

you can download the Moles framework from here, or even better

download the Pex testing framework (that includes Moles) from here.

(I will survey the Pex framework in one of the upcoming posts).

 

the code sample for this post is available here.

 

How do you test the correctness of the following method?
Code Snippet
  1. public class MyComponent
  2. {
  3.     private DateTime _lastHit = DateTime.MinValue;
  4.     
  5.     public bool IsActive()
  6.     {
  7.         if(_lastHit.AddMinutes(20) > DateTime.Now)
  8.             return false;
  9.         _lastHit = DateTime.Now;
  10.         return true;
  11.     }
  12. }

as you can see in line 7, IsActive will be activate only once every 20 minutes.

so should the test wait 20 minutes as shown in the next snippet (line 11):

Code Snippet
  1. [TestMethod()]
  2. public void IsActiveFlowOverDurationTest()
  3. {
  4.     var target = new MyComponent();
  5.     bool actual;
  6.     actual = target.IsActive();
  7.     Assert.AreEqual(true,actual);
  8.     actual = target.IsActive();
  9.     Assert.AreEqual(false, actual);
  10.     
  11.     Thread.Sleep(TimeSpan.FromMinutes(20.1));
  12.  
  13.     actual = target.IsActive();
  14.     Assert.AreEqual(true,actual);
  15. }

 

Moles

the Moles framework is giving us the ability to isolate our tests,

by faking Microsoft, 3rd party or even our own dependencies.

 

I will start with showing the code of our Moles test, and proceed with

some explanation.

Code Snippet
  1. [TestMethod()]
  2. [HostType("Moles")]
  3. public void IsActiveFlowOverDurationTest()
  4. {
  5.     var target = new MyComponent();
  6.     bool actual;
  7.     actual = target.IsActive();
  8.     Assert.AreEqual(true,actual);
  9.     actual = target.IsActive();
  10.     Assert.AreEqual(false, actual);
  11.     
  12.     var moleTime = DateTime.Now.AddMinutes(20.1);
  13.     MDateTime.NowGet = () => moleTime;
  14.     //Thread.Sleep(TimeSpan.FromMinutes(20.1));
  15.  
  16.     actual = target.IsActive();
  17.     Assert.AreEqual(true,actual);
  18. }

what’s has been changed from our previous test method is the attribute on line 2

(which is a decoration for the Moles framework) .

and lines 12-13 which replacing line 14.

as you can see no waiting is involve.

 

another important line that we should add to the assembly level is:

  1. [assembly: MoledType(typeof(System.DateTime))]

which define that we molding the DateTime type.

 

How to add Moles?

adding Moles is very simple, at the testing project add new item and select "Moles and Stubs for Testing"

Moles,Pex,Test,UnitTest,Isolation,Mock

it is very important to name the item after the name of the assembly that you want to fake.

 

Back to the test method

as we saw earlier only 2 line had changed  in our test method:

Code Snippet
  1. var moleTime = DateTime.Now.AddMinutes(20.1);
  2. MDateTime.NowGet = () => moleTime;

as you can see line 1 has nothing to do with Moles.

line 2, is faking the DateTime.Now.

the faked type name is starting M (this is how Moles work and the type is available

because we added the Moles item into the testing project),

and when ever we are faking property, Get or Set will be add as suffix of the property name.

so that how DateTime.Now become MDateTime.NowGet.

 

to supply alternative value all you have to do is to assign a delegate

which returns the faked value.

 

Summary

I didn’t got into the subject of test design, but Moles is giving us fairly powerful

framework which is capable of faking CLR or 3rd party types.

you may want to take Moles farther to file system or database access.

 

as I always say do not wait for your test, let them wait for you :-)

 

beyond the DateTime sample Moles is a great way for isolating your testing

unit from their dependencies (and of course that there are many other god and

sometime better way to do that isolation, like mocking, Mef, Ioc and more).

 

Resources

http://channel9.msdn.com/posts/Peli/Moles-Replace-any-NET-method-with-a-delegate/

http://social.msdn.microsoft.com/Forums/en-US/pex/threads/

 

תגים של Technorati:‏ ,,,

 

Shout it kick it on DotNetKicks.com


Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>