Nikolai Tillmann: Moles - Replace any .NET method with a delegate

Sign in to queue

Description

IMPORTANT! Moles is now the Fakes Framework in Visual Studio 11. Learn more at https://aka.ms/vs11-fakes.

Nikolai Tillman, a member of the RiSE group at Microsoft Research, gives a short demo of Moles, a new framework that allows replacing any .NET method with a delegate. In the context of unit testing, one can use Moles to isolate from environment dependencies (such as time, file system, database, etc...) even when those dependencies are hard-coded through static method or sealed types. In this demo, Nikolai goes through the famous Y2K bug and how to test it...

The Research in Software Engineering team (RiSE) coordinates Microsoft's research in Software Engineering in Redmond, USA.

Embed

Download

Download this episode

The Discussion

  • User profile image
    gbrayut

    Very cool! One question: Does Moles work with other test frameworks (NUnit, MbUnit, ...) or just with the Visual Studio testing framework.

     

    Also where can I buy one of those whiteboards Tongue Out It looks to be an EduBoard interactive whiteboard P3000, but they don't appear to have any retailers in the US.

     

    Keep up the great work!

  • User profile image
    peli

    Moles work with any .NET executable, i.e. with any test framework that has a console application. We provide a better integration experience for Visual Studio Unit Test because it supports hosting. In the samples that ship with Pex/Moles, you will also find custom test framework extensions for NUnit, xUnit.net and MbUnit that allow a smooth integration. Don's hesitate to ask any questions on this on our forums.

     

    It is not even a whiteboard, it is just a projector and a eBeam Whiteboard device Wink

  • User profile image
    bondsbw

    Nice!  Now, if you could convince the C#/CLR guys to add this to the next release, so that the DLL generation was unnecessary...

     

    In other words, I would like it if you could change the syntax of that added line of code to something like:

     

    override get DateTime.Now = () => new DateTime(2000, 1, 1);

    
    
    
    
  • User profile image
    peli

    Very cool syntax indeed... but let's climb one mountain at a time Smiley

  • User profile image
    Adam​Speight2008

    Am I the only one where this seem wrong by calling this testing when you modify the code by inserting

     MDate.GetNow = () => New Date(2000,1,1)

     

    Or am I missing something.

     

    Idea add a attribute to the class,method etc, where within that scope the GET is intercepted and the test value is returned.

    For Example:-

    <Test.InterceptGet("System.Date.Now",() => new Date(2010,4,1))>

  • User profile image
    NeZz_DK

    when we do testing we test a class at a time, so all external stuff is either stubbed or mocked so that you just test the functionality of the single class instead of doing system wide testing that are a nightmare to maintain. and if you test every single layer and it behaves as you expect while testing than everything should be good atleast from the code standpoint.

     

    I can see alot of places where we can use this while doing ASP.NET at least.

  • User profile image
    peli

    By isolating your tests for environment dependencies, you make your tests deterministic, fast and easier to setup. This is very important for unit testing. This Isolated tests do not replace integration tests: you still have to run your code in end-to-end scenarios.

     

    The attributes would not work for a number of reasons: you cannot declare delegates in attribute constructors. The string identifier is not verified by the compiler (in fact your example is wrong). Moles are strongly typed. In general, generics and all this good stuff would make it really hard to use any kind of attribute based solution.

     

  • User profile image
    peli

    The new version of Pex (0.22) ships with an example of Moles for Asp.NET (HttpContext, HttpRequest). Unzip the samples.zip that the installer produces and look under \Behaviors\System.Web.Behaviors.

     

  • User profile image
    Adam​Speight2008

    That's why it was any Idea. Implementing is the idea down to smarter brains than mine.

    Maybe I should have explained in more detail

    The idea was when the code is run in "Test Mode" the Test Engine recognises that that class has a Test attribute.

     So read the string part "System.Date,Now" which is interpted to mean that that method is called for by the CLR I want to use the alternative version.

     The alternative version is provided via a func ( The Lamba Expression )

     

    Shame about the attributes, having to be a constant expression, because its converted to metadata, I think having a func would be useful.

    Imagine you have an AddressOf and point it a function contained in a test module.

  • User profile image
    Richard.Hein

    One of the key barriers to useful unit testing has been solved.  Fantastic work, it will be useful immediately.

  • User profile image
    peli

    The attributes won't work: AddressOf works for types not methods, even if it would, the attribute would sit in the project under test and could not refer to the test project (chiken and egg problem). In any case, things can become more intricate when you apply Moles to non-toy examples.

     

    That being said, your idea of being able to switch between a isolated test mode and an integration mode is good. This is something we want to provide in the future but still a big question mark on how we are going to implement it.

  • User profile image
    voneinem

    Great!

    Looks like an inexpensive replacement for TypeMock which already is able to mock DateTime.Now.

     

    Question: This justs creates another implementation for DateTime.Now. If I have a function I want to test that uses DateTime.Now and DateTime.UtcNow as well, I need to mock both, right?

  • User profile image
    robcube

    Instead of using Pex Moles, why not do it in a "library-less" way with something already built in?

     

    http://ayende.com/Blog/archive/2008/07/07/Dealing-with-time-in-tests.aspx

  • User profile image
    peli

    Yes, you will have to add a mole for UtcNow:

     

        var now = new DateTime(2000,1,1);

        MDateTime.UtcNowGet = () => now;

        MDateTime.NowGet = () => now.ToLocalTime();

     

     

  • User profile image
    peli

    If you have the opportunity of introducing an abstraction layer between the environment and the code (in your example, DateTime.Now is abstracted by a delegate), you should defintely do it. Moles is useful when you do not have a choice (for a number of reasons) and system under test has hared-coded dependencies.

     

    In both cases, the Pex parameter generation can be used to improve code coverage.

  • User profile image
    dpurrington

    This is great stuff! Nothing more aggravating than having to pry a class loose from its dependencies on these kinds of things. Looking forward to trying this out with NUnit.

  • User profile image
    BennyG

    Nice, but have a look on F# Object Expressions. I already use F# in my Unit-Tests for mocking interfaces.

    With Object Expression you could write something like :

     

    let obj1 = { new System.Object() with member x.ToString() = "F#" }

    or

    let personComparer = {
    new
     IComparable<Person> with
     

     

    but you cannot write this, because DateTime is sealed.

     

    let now = {
    new
     System.DateTime() with
    member
     x.Now() = new
     DateTime(2000,1,1) }

     

    Benny

    
        member this.Compare(a,b) =
    
               if a.First
     > b.First then
     1
               elif
     a.First = b.First then
     0
    
               else
     0 }

  • User profile image
    peli

    The point of Moles is to deal with hard mocking situations: sealed classes, static methods, non-virtual methods, etc...

  • User profile image
    patelabhije​et

    Run that by Eric Lippert  <grin>

  • User profile image
    johnman

    Is there any way Moles could be used for a .NET 2 project. Looking at the download page it looks like you support VS2010 and VS2008. Can you use 2008 and target the .NET 2 framework and still use Moles?

     

    Thanks,

     

    John

  • User profile image
    peli

    Absolutely. We can also answer further questions at https://social.msdn.microsoft.com/Forums/en-US/pex/threads/

  • User profile image
    gene.mangrum

    The video is prompting for a username and password.  Is it not available now?

     

  • User profile image
    peli

    Must have been a temporary glitch, it's working for me now.

  • User profile image
    CodeDigger

    no offence ment but: video cam following somebody around is distracting, gives 0 additional insight and just occupies bandwidth

  • User profile image
    Colin

    How can I use this with Silverlight?

  • User profile image
    Ryan Morgan

    Seconded... is there a plan to make this available for the Silverlight runtime?

  • User profile image
    coderp

    Hello guys.
    I was wondering if Pex and Moles is compatible with using Microsoft Unity. I am working on a sharepoint project now and we plan to use Microsoft Unity to give flexibility to the project. Still - I couldn't find much information about that, so I just wanted to ask here.
    Cheers

  • User profile image
    Dharmesh​Tailor

    Hi, i used moles and its working great for my project, but the only problem is i am using NUnit and my assembly have about 1000 unit tests and i just want to run only single tests then how can i do that. i have used moles addin for NUnit and still NUnit gives the error for instrumented process so i decided to execute test with moles.runner.exe console but it takes whole assembly and i just want to test a single test. any advice and suggestion will be helpful. thanks in advance

  • User profile image
    Dan

    @AdamSpeight2008
    I agree with you - it's a really cool tool, but this is a really poor test example. 
    That being said, I think the goal was to boil down to the essence of moles, and readers here can likely all imagine how it could be used for real.

  • User profile image
    Roland

    If I was to disassemble using ILSpy your example. What would the generated code look like?

Add Your 2 Cents