Ever wanted to fake collections or perform dynamic-language style behavior faking? Get the new Isolator version 5.1.1! This version received a minor version notation because we still have some major features up our sleeve, but it still sports cool new features, namely:
Duck-type swapping:
The saying “If it walks like a duck and talks like a duck, it must be a duck” is often used to illustrate concepts behind dynamic languages. Identifying an object by its behavior, rather than by its declared type, adds a programming language with powerful and flexible descriptive capabilities – just see what Microsoft is up to in C# futures. We took the idea of behavior-based type inference into the behavior faking world with the new Isolator swapping features:
1 |
<span class="rem">// both the duck and the dog can talk. Normally a duck goes "Quack!" and a dog goes "Woof!"</span><br />var duck = <span class="kwrd">new</span> Duck();<br />var dog = <span class="kwrd">new</span> Dog();<br /><br /><span class="rem">// Once we swap the two...</span><br />Isolate.Swap.CallsOn(duck).WithCallsTo(dog);<br /><br /><span class="rem">// ...we have a duck going "Woof!"</span><br />Assert.AreEqual(<span class="str">"Woof!"</span>, duck.Talk()); |
Besides the novelty value and endless options dealing with duck and dogs (you can make ducks chase cars or go fetch!), this is useful in unit testing. When you want to replace an object you are dependant on with a stand-in implementation this is a simple and powerful mechanism.
Collection handling:
A lot of support cases we saw recently pointed out difficulties when handling collections with Isolator. This is a frequent yet complex problem we are addressing with this release. Basically it comes with two sub features: collection value swapping and automatic collection faking.
Collection value swapping: we can now replace values of collections in the code under test with test data collections we prepare for this purpose. The API is pretty simple too:
1 |
<span class="rem">// swap the Calculation.Numbers collection property with our own collection of numbers</span><br />Isolate.WhenCalled(() => Calculation.Numbers)<br />.WillReturnCollectionValuesOf(<span class="kwrd">new</span>[] {1, 3, 5});<br /><br /><span class="rem">// when iterating over the collection or accessing its members we receive the test values</span><br />Assert.AreEqual(3, Calculation.Numbers[1]);<br /><br /><span class="kwrd">int</span> sum = 0;<br /><span class="kwrd">foreach</span>(var number <span class="kwrd">in</span> Numbers)<br />{<br />sum += number;<br />}<br />Assert.AreEqual(9, sum); |
Automatic collection faking: when modifying behavior for a call chain which includes a collection index access, we assume you would like to fake out all elements in that collection up to the one in the index we are modifying. With auto-collection faking this is done automatically: when setting behavior for a collection element, all elements of a lower index are automatically created and assigned with recursive fake objects. Here’s a practical example from the SharePoint world:
1 |
<span class="rem">// create a fake SPSite - this is the top level in the SP object model</span><br />SPSite fakeSite = Isolate.Fake.Instance<SPSite>(Members.ReturnsRecursiveFakes);<br /><br /><span class="rem">//make the 3rd list's 2nd item have a specific name and ID</span><br />Isolate.WhenCalled(() => fakeSite.OpenWeb().Lists[2].Items[1].Name).WillReturn(<span class="str">"Test Item"</span>);<br />Isolate.WhenCalled(() => fakeSite.OpenWeb().Lists[2].Items[1].ID).WillReturn(999);<br /><br /><span class="rem">// Underlying lists are created automatically</span><br />Assert.AreEqual(3, fakeSite.OpenWeb().Lists);<br /><br /><span class="rem">// We can iterate over all lists and items and query them</span><br /><span class="kwrd">int</span> id = SharepointHandler.GetIdForListItem(fakeSite, "Test Item");<br />Assert.AreEqual(999, id);<br /><br /><span class="rem">// example implementation of GetIdForListItem() for reference:</span><br /><span class="kwrd">public</span> <span class="kwrd">int</span> GetIdForListItem(SPSite site, <span class="kwrd">string</span> itemName)<br />{<br /><span class="kwrd">using</span>(SPWeb web = site.OpenWeb())<br />{<br /> <span class="kwrd">foreach</span>(var list <span class="kwrd">in</span> web.Lists)<br /> {<br /> <span class="kwrd">foreach</span>(var item <span class="kwrd">in</span> list.Items)<br /> {<br /> <span class="kwrd">if</span>(item.Name == itemName) <span class="kwrd">return</span> item.ID;<br /> }<br /> }<br />}<br />} |
What do you think? go ahead and download the new version and let us know.