Click here to Skip to main content
15,896,557 members
Articles / Programming Languages / C# 4.0

Parrots, A "record and replay" Mocking/Stubbing Library

Rate me:
Please Sign up or sign in to vote.
4.83/5 (6 votes)
1 Oct 2011BSD16 min read 27K   252   14  
Parrots is a "record and replay" mocking/stubbing library introducing a new concept in the "mocking" area.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--------------------------------------------------------------------------->  
<!--                           INTRODUCTION                                

 The Code Project article submission template (HTML version)

Using this template will help us post your article sooner. To use, just 
follow the 3 easy steps below:
 
     1. Fill in the article description details
     2. Add links to your images and downloads
     3. Include the main article text

That's all there is to it! All formatting will be done by our submission
scripts and style sheets. 

-->  
<!--------------------------------------------------------------------------->  
<!--                        IGNORE THIS SECTION                            -->
<html>
<head>
<title>The Code Project</title>
<style>
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
H2 { font-size: 13pt; }
H3 { font-size: 12pt; }
H4 { font-size: 10pt; color: black; }
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
</style>
<link rel="stylesheet" type="text/css" href="http://www.codeproject.com/App_Themes/NetCommunity/CodeProject.css">
</head>
<body bgcolor="#FFFFFF" color=#000000>
<!--------------------------------------------------------------------------->  


<!-------------------------------     STEP 1      --------------------------->
<!--  Fill in the details (CodeProject will reformat this section for you) -->

<pre>
Title:       Parrots, a &quot;record and replay&quot; mocking/stubbing library
Author:      Wasp.NET
Email:       roby@robychechi.it
Language:    C# 4.0
Platform:    Windows
Technology:  .NET Framework, unit testing
Level:       Intermediate
Description: The article is about Parrots, which is a library introducing a (possibly) new concept about &quot;record and replay&quot; mock/stub objects for unit testing
Section      
SubSection   
License:     BSD 3-Clause License
</pre>

<!-------------------------------     STEP 2      --------------------------->
<!--  Include download and sample image information.                       --> 

<ul class=download>
<li><a href="wasp-parrots.zip">Download source - 6.842 Kb</a></li>
</ul>

        <h2>Parrots, a &quot;record and replay&quot; mocking/stubbing library</h2>
        <p>
        <strong>Parrots</strong> is a library introducing 
        a (possibly) new concept about &quot;record and replay&quot; mock/stub objects 
            for unit testing. It is written in C# over .NET Framework 4.0, and it has been 
            tested over C# samples only. It does not use any particular feature of the .NET 
            Framework which was not available in 3.5 version, but for certain future 
            features I&#39;m considering using <i>dynamic typying</i>, so I will probably stick 
            with 4.0.</p>
        <h3>
            Background 
        </h3>
        <p>
        Let&#39;s suppose I cannot do TDD for 
        whatever reason, and for the same reasons I end up writing &quot;unit tests&quot; but 
        injecting &quot;true&quot; dependencies to my &quot;system under test&quot; (SUT). We all know that 
        these are not “true” unit tests, but they happen to be a good development tool 
        anyway and I don&#39;t see why I should not use them. So, should I at some point &quot;convert&quot; them to 
            &quot;true&quot; unit tests by &quot;mocking&quot; the 
        concrete dependencies with a good mocking library like 
            <a href="http://hibernatingrhinos.com/open-source/rhino-mocks" target="_blank">Rhino Mocks</a>? 
            Probably yes, but 
        again, maybe I have no time and, honestly, many times doing mocks is a quite 
        long, tedious, complex and error prone activity, even more if I do no really 
        care about mocks but only about supplying my SUT with stable and predictable 
        dependencies. I just would like to have &quot;stubs&quot;, forget about them and have my 
        tests go green... </p>
        <p>
            That&#39;s how <strong>Parrots</strong> gets involved: I go on writing &quot;integration tests&quot;, which 
        talks to the concrete dependencies I already have available, but later at some 
        point I tell my tests, through <strong>Parrots</strong>, to &quot;record&quot; the conversations happening 
        between SUT and its dependencies. As soon as I do it, the tests convert 
        themselves to use the recordings <strong>Parrots</strong> did for me, and since then they will 
        stop talking to concrete implementations and switch to the &quot;imitations&quot; <strong>Parrots</strong> 
        did for me. Now you know why this curious name... :)</p>
        <p>
            The first time you execute 
        such a test, the SUT will talk to the concrete dependencies I configured with my 
        preferred <i>IoC container</i>, and <strong>Parrots</strong> will be recording whatever info they 
        exchange. The usage of an IoC container is very important, and it is mandatory 
        so far because <strong>Parrots</strong> is able to use interception features all good IoC 
        containers supply. It is possible that this part will evolve in slightly 
        different directions, making the usage of IoC containers optional, but that&#39;s not 
            the case so far, because I’ve been considering that doing inversion of control 
            is always a good thing to do, so I hope this is not a big problem for potential 
            users. Right now <strong>Parrots</strong> talks to 
            <a href="http://www.castleproject.org/" target="_blank">Castle Windsor</a> only, but it would be nice to have 
        more of them.</p>
        <p>
            Nothing new so far, but when we execute our test again, and without changing the unit test 
        code, <strong>Parrots</strong> will enter, and it will redirect the dialogues between SUT and 
        dependencies to &quot;somewhere else&quot;, where recorded info can be retrieved and sent 
        to the SUT transparently. The concept is similar to a mock, but the info 
        exchanged are recorded and replayed. I’m using the “mock” term because it is 
        largely known and understood, but technically it might not be the best way to 
        describe this technique, because normally “mock objects” are programmable and are supposed to be able 
        to deliver information about how they have been used, which <strong>Parrots</strong> does not. 
            <a href="http://martinfowler.com/articles/mocksArentStubs.html" target="_blank">Probably it would be better to define them as “stub” objects</a>, but I fear this 
        does not communicate as much as “mock” word does. Anyway, <strong>Parrots</strong> approach is 
            slightly different from both stub and mock objects, so a new term should be 
            used... probably <i>parrot objects</i> would work :)</p>
        <h3>
            Dissecting parrots...</h3>
        <p>
        Now 
        that you have some ideas about what it is all about, let&#39;s go deeper to 
        understand what <strong>Parrots</strong> can do, and how, by inspecting a sample unit test:</p>
        <pre>[Test]
public void SimpleStringTest() { 
    var imitation = Trainer.Aviary
        .AddParrotFor&lt;IAmSomeDependency&gt;()
        .And.AddParrotFor&lt;IAmSomeOtherDependency&gt;()
        .Finally.RecordOrReplay();

    var sut = new ToBeTested(imitation.Resolve(), imitation.Resolve()); 
            
    var output = sut.Process(&quot;repeat&quot;, &quot;wasp&quot;); 
            
    Assert.AreEqual(&quot;waspwasp&quot;, output); 
            
    imitation.ReleaseParrots();
}</pre>
        <p>
            At the beginning of our test we can see a &quot;fluent&quot; call creating an imitation, 
            which is a sort of working session where configuration information is stored and 
            from where we can get parrots. If we read it line by line, we can see that we 
            have a <i>parrots trainer</i> owning an <i>aviary</i>, and for every dependency (interface) he 
            needs to imitate he just adds a <i>parrot</i> in the aviary (<code>AddParrotFor()</code> 
            calls). As soon as the trainer is done adding parrots, he finishes the 
            configuration step returning an <i>imitation</i> through the
            <code>RecordOrReplay()</code> call. Behind the scenes several 
            objects are created to keep track of parrots configurations and to give us a 
            fluent interface, and the final method give us the collector of all this 
            information (the <i>imitation</i>).</p>
        <h4>
            Record</h4>
        <p>
        Now we are ready to proceed with our test 
        as if we were dealing with a &quot;classic&quot; unit test. We instantiate our &quot;system 
        under test&quot; (SUT) and we supply it with its dependencies (<code>Resolve()</code> calls). As 
        already mentioned, <strong>Parrots</strong> concepts are completely based on &quot;inversion of 
        control&quot; and &quot;dependency injection&quot; principles, and its currently 
        available implementation lives on top of an IoC container. Today it works with 
        Castle Windsor only, but there is no hard-coded dependency on that, it is loaded 
        dynamically through an ad hoc assembly and configuration directives:</p>
        <pre>&lt;facilities&gt;
    &lt;facility id="parrots" type="Parrots.Bridge.Castle.ParrotsFacility" /&gt;
    &lt;facility id="ms-parrots" type="Parrots.Bridge.Castle.NUnitTestsParrotsFacility" /&gt;
    &lt;facility id="mocking-parrots" type="Parrots.Bridge.Castle.ParrotsMockingFacility" from="Parrots.Bridge.Rhino" /&gt;
&lt;/facilities&gt;</pre>
        <p>
            The first, and most important, directive injects in <strong>Parrots</strong> the 
            right interception engine, which leverages Castle Windsor and Castle 
            DynamicProxy features; the second one tells <strong>Parrots</strong> which kind 
            of unit test framework I am using; the last one configures the appropriate 
            &quot;true&quot; mocks generation engine (see the last section of tjis document). I hope to support more different 
            IoC containers 
        soon.</p>
        <p>
            Back to the <code>Resolve()</code> calls, we use our imitation in a way which is similar to what we do with a 
        &quot;mocks repository&quot;: we ask the imitation for available implementations of 
        dependency contracts our SUT needs. Let&#39;s suppose it is the first time we launch 
        our test: what does our imitation do? Well, for each requested interface he 
        looks for a corresponding configuration built through <code>AddParrotFor()</code> 
            calls, and if it does not find any it simply 
        lets the IoC do the work for us, becoming &quot;transparent&quot;. But if it does find a 
        configuration, he creates a corresponding parrot, which is the truly interesting 
        actor here. Like a real parrot, he just stands there side by side of the needed 
        dependency, listening every single conversation happening with the SUT, and 
        recording it. Technically, an &#39;interceptor&#39; is put in place, connecting the 
        dependency and its imitating parrot, which will take note of everything. There 
        are more technical details which should be discussed, along with still missing 
        things, but I want to keep it simple here.</p>
        <p>
            After the SUT setup phase, it goes on with usual code: there are calls towards 
        the SUT and “asserts”. It is in this phase that parrots listen and record 
        conversations, and this phase ends when the <code>ReleaseParrots()</code> method is called on 
        the session. That method “frees” our parrots, but just before releasing them it gets all 
        the interesting info they recorded and persists it on binary files with a 
        specific structure and naming convention, and in a specific position. Those 
        details are hard-coded so far, and based on conventions, but they will be more 
        configurable soon. Please notice that it is also supported the using idiom based 
        on <code>IDisposable</code>, where the <code>Dispose()</code> call does the same 
            <code>ReleaseParrots()</code> call do; 
        you may check the unit tests code to see samples using it.</p>
        <h4>
            Replay</h4>
        <p>
            Ok, we are done with 
        recording, and we decide to launch our test again. The start-up phase is the 
        same, but when we get to the <code>Resolve()</code> calls something 
            different happens, because the session checks if recordings are available for 
            each parrot, and if it finds them it uses them to build parrots that &#39;already learned their lesson&#39;, 
        and are able to repeat what they listened before. The true dependencies are 
        still created, but the method calls are replaced by “proxy calls” based on 
        recorded info, completely replicating the dependencies behaviors we obtained 
        when we launched the test the first time. So, since the second execution of a 
        test method, its dependencies are not executed anymore: our &#39;integration test&#39; 
        is becoming a true &#39;unit test&#39;! I’d like to find a way to avoid the concrete 
        instantiation of our dependency, this is an issue <strong>Parrots</strong> currently has which 
        might be a problem in scenarios where dependencies do “stuff” in their 
        constructors, I will work on it in the next weeks looking for a solution, I already 
            have a couple of ideas and I just need some time to implement them.</p>
        <p>
            A 
        couple of considerations might be useful: </p>
        <ul>
            <li>conversation recording is not that 
        simple, and conversations can be very complex in terms of parameters and return 
        value types, we have to deal with delegates for callbacks, non serializable 
        types, exceptions and so on. Most of those details have been faced and 
        implemented, but maybe something is missing or not yet perfect.</li>
            <li>if we record a 
        test and later we change its code introducing or removing new calls or asserts, 
        chances are that our recording will not be correct anymore: our parrot will not 
        be able to repeat things he did not listen. The idea is that every single 
        modification in our test that changes the interaction sequence with our 
        dependencies requires repeating the recording for the modified test(s). Here the 
        “contract” is quite strong: even changing the calls sequence is a breaking 
        change of the whole imitation, and requires recording again the test. Let&#39;s dig 
        deeper about this point.</li>
        </ul>
        <h3>
            Call Sequence Equivalence</h3>
        <p>
            As already mentioned, 
        <strong>Parrots</strong> does its job recording every single conversation happening between our 
        SUT and its dependencies under imitation. When a recording is available and we 
        launch a test, <strong>Parrots</strong> starts comparing the &quot;call sequence&quot;, and at every single 
        step (call) it retrieves what has been recorded about that step, in terms of 
        which dependency was the target, which method was called, which parameters were 
        supplied and which return values the method produced. Every single unit test 
        methods gets its own call sequence, and <strong>Parrots</strong> is happy only if the whole 
        sequence is replayed exactly as it has been recorded the first time. If, for 
        example, we slightly change our unit test after it has been recorded, and our 
        changes modify the call sequence, <strong>Parrots</strong> will throw an exception and our test 
        will fail. I decided to be quite strict about this because, IMO, such a unit 
        test should be treated by <strong>Parrots</strong> as a contract, and changing the contract 
        invalidates the recordings. But, what does <strong>Parrots</strong> do to understand if a 
        sequence has been changed? Well, it seems quite simple. If we launch our unit 
        test after it has been already recorded, that&#39;s what happens behind the scenes 
        (this is a conceptual description, the true code sequence might be slightly 
        different): </p>
        <ol>
            <li>when <strong>Parrots</strong> intercepts the first call to whatever intercepted 
        dependency, it retrieves the corresponding first recorded call in the available 
        sequence</li>
            <li>for that call, he checks if the method names from the current call 
        and from the recorded call are equal</li>
            <li>if they are, it does the same for every 
        input parameter</li>
            <li>if they all pass the test, it assigns the recorded answer and 
        any output parameter to the current call context, avoiding any call to the true 
        dependency, and then it lets the test go on</li>
        </ol>
        <p>
            These steps are repeated for every 
        other call in the current sequence, breaking this loop if a difference in any step is 
        found. What we did not discuss yet is how <strong>Parrots</strong> understands when the method 
        name and the parameters &quot;are equal&quot;. For the method name it is an easy job: we 
        just compare method name strings for equality, and we are done. But when we have 
        to deal with input parameters, things get harder, because the &quot;equality 
        semantics&quot; for each parameter might be a problem. Let&#39;s see an example:</p>
        <pre>[Test]
public void GraphTestWithEqualityFunctor() { 
    var imitation = Trainer.Aviary 
        .AddParrotFor&lt;IAmSomeDependency&gt;()
        .Finally.RecordOrReplay(); 
        
    var sut = new ToBeTested(imitation.Resolve(), imitation.Resolve()); 
    
    var head = new GraphHead(&quot;head&quot;); 
    
    var output = sut.Echo(head); 
    
    Assert.AreEqual(&quot;head&quot;, output.Text); 
    
    imitation.ReleaseParrots();
}</pre>
        <p>
Inside the <code>Echo()</code> method, our SUT 
        calls another method on <code>IAmSomeDependency</code> interface, which happens to have this 
        trivial interface: </p>
        <pre>GraphHead Echo(GraphHead head) { ... }</pre>
        <p>
            So, checking the 
        sequence call, it will have no problems in checking for the method name 
        equality, but then it will have to do the same on the head parameter, which is 
        of type <code>GraphHead</code> (this is a sample class type you will find in the unit tests 
        source code). Now, what if <code>GraphHead</code> class does NOT overrides 
            <code>Equals()</code> method? 
        By default, we get &quot;reference equality&quot; semantics, and source and target memory 
        addresses will be compared, and during the replay phase they will be different, 
        making <strong>Parrots</strong> fail. This is not the right place to discuss about equality 
        semantics, let&#39;s just suppose that we are in a scenario where we cannot change 
            <code>Equals()</code> on our type, for whatever reason. How can we fix <strong>Parrots</strong>?</p>
        <h3>
            Behaviors</h3>
        <p>
            <strong>Parrots</strong> has a feature called <i>behaviors</i>, which allows us to drive how 
        <strong>Parrots</strong> must behave when facing our dependencies, and in particular when dealing 
        with methods calls towards them. Let&#39;s see how we can change our unit test:</p>
        <pre>
[Test]
public void GraphTestWithEqualityFunctor() { 
    var imitation = Trainer.Aviary 
        .AddParrotFor&lt;IAmSomeDependency&gt;(
            d =&gt; d.Echo(Understands.Equality((left, right) =&gt; left.Text == right.Text)))
        .Finally.RecordOrReplay(); 
        
    var sut = new ToBeTested(imitation.Resolve(), imitation.Resolve()); 
        
    var head = new GraphHead(&quot;head&quot;); 
        
    var output = sut.Echo(head); 
        
    Assert.AreEqual(&quot;head&quot;, output.Text); 
        
    imitation.ReleaseParrots(); 
}</pre>
        <p>
The only difference is at this line:</p>
        <pre>d =&gt; d.Echo(Understands.Equality((left, right) =&gt; left.Text == right.Text))</pre>
        <p>
The <code>AddParrotFor()</code> accepts a <code>params</code> array of lambda expressions of 
        type <code>Expression&lt;Action&lt;T&gt;</code><Action<T>&gt;, where 
            <code>T</code> is closed to the type passed to 
            <code>AddParrotFor()</code> method. This way we can pass a list of expressions that <strong>Parrots</strong> 
        will inspect to understand how we want it to behave for each specified method. 
        These expressions will never be called, they will just be analyzed in order to 
        find hints about what to do in different moments of the call sequence 
        processing.</p>
        <p>
            Back to our equality problem, we can see that the first (and only) 
        argument to the <code>Echo()</code> method is a special expression built up through a static 
        service class called <code>Understands</code>, which exposes several methods with the only 
        goal to be &quot;called&quot; inside behavior expressions. The <code>Understands.Equality</code> call 
        allows us to specify that <strong>Parrots</strong>, when comparing two instances of 
            <code>GraphHead</code> 
        type, will have to use the anonymous method we are specifying as the 
            <code>Equality()</code> 
        method argument. This way we are able to supply necessary equality semantics for 
        each test, making them go green accordingly to what &#39;equality&#39; means in the 
        context of our test. <code>Equality()</code> methods also support supplying any type which 
        implements <code>IEqualityComparer</code> with a default constructor. Behaviors are an 
        interesting feature we can use to tweak other details, they are still under 
        development, but through them you will already be able to do things like, for example, 
        declaring that certain arguments should just be skipped during call sequence 
        equality checks. If your dependencies must be supplied with arguments like 
            <code>DateTime.Now</code>, which will never be the same at every test execution, or if they 
        need references to “service instances” which do not expose meaningful identity or 
        state (like, for example, an implementation of <code>IFormatter</code> interface 
            likely would), with <code>Understands.Any()</code> you will have the right tool to tell <strong>Parrots</strong> to just 
        skip them. <code>Understands.Any()</code> and similar methods are already available, while other 
            related methods 
        will be released soon.</p>
        <h3>
            Public representation</h3>
        <p>
            Equality semantics can be a quite 
        hard topic to manage, and if you start doing parrots for dependencies which use 
        parameters or return values which don’t manage equality correctly, you may find 
        unexpected test failures. In such cases it would be very hard for <strong>Parrots</strong> to 
        distinguish between real failures because of changes introduced in the SUT, and 
        failures which come from equality issues. So I decided to implement an 
        additional feature, which is enabled by default, which is based on the <i>public 
        representation</i> concept: two values of any type used as a parameter may be 
        considered having the same “public representation” if a deep compare of their 
        public properties ends up finding the same values. This is a sort of surrogate 
        for equality, which is indeed arguable and might not be satisfying for many 
        reasons, therefore <strong>Parrots</strong> allows you to disable it on every parrot calling 
            <code>With.PublicRepresentationEqualityDisabled()</code> on it. If this feature is enabled, 
        <strong>Parrots</strong> detects when equality checks fail but “public signatures” match, 
        raising a specific and verbose exception which alerts the programmer about a 
        potential problem related to equality, letting him decide how to manage it. In 
        general, <strong>Parrots</strong> raises quite verbose and descriptive exceptions, trying to help 
        detecting where the change in the SUT occurred. This is accomplished showing 
        which dependency and call failed, which parameters where supplied and which 
        position in the call sequence it occupies.</p>
        <h3>
            &quot;True&quot; mocks</h3>
        <p>
            So far our discussion tried to illustrate the &quot;record and replay&quot; scenario, 
            which is the main one, but there is more: if 
        you change the <code>RecordOrReplay()</code> method to 
            <code>GenerateOrReplay()</code>, <strong>Parrots</strong> will not 
        just record the traffic, but it will also generate true Rhino Mocks code (again, 
            this is not an hard coded dependency and it is possible that in future more 
            mocking libraries will be supported), following the <i>Arrange/Act/Assert</i> pattern. 
            Ok, this is not completely true: &quot;AAA&quot; 
        should mean you can clearly read the <i>Arrange</i> and the <i>Assert</i> part in the body of 
        the unit test along with the <i>Act</i> part, and that&#39;s not the case, but the 
            <i>Arrange</i> 
        and <i>Assert</i> parts are nicely isolated and should be easy to find, so let&#39;s 
            keep this definition. <strong>Parrots</strong> 
        will put the generated code in a well-known place (soon it will be 
        configurable), and you will just have to include the generated code in your unit 
        tests project, modifying it at your will if you think that it can be improved. 
        This way you would have true mocks with almost no effort. If you just let the 
        <strong>Parrots</strong> code in place even after including the generated code, <strong>Parrots</strong> will 
        transparently load the generated mocking code without having you to modify 
        anything in order to “turn on” Rhino repositories!</p>
        <p>
            At this point, I must be 
        honest: the features about generating &quot;true&quot; mocks are far from be complete, and 
        it is very possible that they will never be as complete as I&#39;d like to for many 
        reasons (the most important one: it is a difficult thing to do!). Probably the 
        best <strong>Parrots</strong> will ever be able to do is generating complete mocks for “simple” calls 
        and types, and useful but incomplete <i>placeholders</i> for more complex mocks, which will need manual 
        interventions to become fully functional. I&#39;ll try to make my best to generate 
        smart placeholders, but so far I&#39;m not able to guarantee that this feature will 
        be more than a nice helper.
        </p>
    

        <h3>
            Summary</h3>
        <p>
            <strong>Parrots</strong> is in a quite early stage, and its code still needs 
            some cleanup and refactoring, but there are already several things the 
            library can do and enough features to have them evaluated. You will find out more about it browsing the code and analyzing the unit tests 
        contained in the solution, and the project will evolve in time. You can check its 
            current status <a href="https://bitbucket.org/wasp/parrots" target="_blank">here</a>.</p>
    

</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The BSD License


Written By
Software Developer (Senior) Umanova (CH)
Italy Italy
Working as an IT consultant since 1995, and on C# and .NET Framework since they were born. Actually consulting in Geneva (CH).

Comments and Discussions