<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Dennis Burton's Develop Using .NET</title>
    <link>http://developusing.net/</link>
    <description>Change is optional. Survival is not required.</description>
    <language>en-us</language>
    <copyright>Dennis Burton</copyright>
    <lastBuildDate>Sun, 27 Sep 2009 02:58:18 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>dennis@developusing.net</managingEditor>
    <webMaster>dennis@developusing.net</webMaster>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/DevelopUsingdotnet" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=9e5ebee3-0209-45fd-a189-4c1b98541296</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,9e5ebee3-0209-45fd-a189-4c1b98541296.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,9e5ebee3-0209-45fd-a189-4c1b98541296.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9e5ebee3-0209-45fd-a189-4c1b98541296</wfw:commentRss>
      <title>JDRF – Walk to cure diabetes</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,9e5ebee3-0209-45fd-a189-4c1b98541296.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/sOc0_LTNaVo/JDRFWalkToCureDiabetes.aspx</link>
      <pubDate>Sun, 27 Sep 2009 02:58:18 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;On October 4th and October 10th, my family will be participating in &lt;a href="http://walk.jdrf.org/index.cfm?fuseaction=extranet.personalpage&amp;amp;confirmid=87302348"&gt;fund raising walks&lt;/a&gt; to raise money for research into better management, and someday a cure, for diabetes. Similar to many of the technical conferences I attend, these events provide a great place to get tips and tricks, and to share stories of shared experiences. As parents, we walk away from these events refreshed with new ideas and comforted that our struggles are shared. It is also a good place for my son Drew to be around other kids who have diabetes--a place where it is not unusual to do a blood sugar test before lunch. &lt;/p&gt;  &lt;p&gt;Since &lt;a href="http://developusing.net/2008/10/07/StepOutToFightDiabetes.aspx"&gt;last year&lt;/a&gt;, Drew has now moved on to first grade. He has become a voracious reader, loves launching model rockets, riding his bike, and of course, pestering his little brother. He lives a very full life, just like any other 6 year old boy, with a bit more ceremony around eating, exercise, and bedtime. One of his favorite activities is driving, whether it is Power Wheels, the lawn tractor, or popping dad’s car out of gear and releasing the emergency brake for a fun-filled ride into &lt;a href="http://developusing.net/content/binary/car_in_ditch_small.jpg"&gt;the ditch&lt;/a&gt;; he relishes every minute behind the wheel. As any 6 year old should, he now knows the tune to &lt;a href="http://en.wikipedia.org/wiki/The_Victors"&gt;The Victors&lt;/a&gt; and most of the words. In short, this little guy does not let anything keep him from enjoying being a kid.&lt;/p&gt;  &lt;p&gt;Through all of the cake and ice cream ridden birthday parties, hormone changes, and marathon play sessions, control has been pretty good so far this year. The last three A1c readings have been at 7.1%. The goal that we have been given by the endocrinologist is 8%. We try very hard, as parents, to learn and teach how to deal with life with diabetes so that Drew will have all the knowledge he needs to significantly reduce the risk of common complications. Through events like this walk, my hope is that in my lifetime, management of this disease will not be a 24/7 activity. If you would like to help support us in this endeavor, you can sponsor our team here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://walk.jdrf.org/index.cfm?fuseaction=extranet.personalpage&amp;amp;confirmid=87302348"&gt;JDRF Team Donation Page&lt;/a&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=9e5ebee3-0209-45fd-a189-4c1b98541296"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=sOc0_LTNaVo:EB0_hojKJqA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/sOc0_LTNaVo" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,9e5ebee3-0209-45fd-a189-4c1b98541296.aspx</comments>
      <category>diabetes</category>
    <feedburner:origLink>http://developusing.net/2009/09/27/JDRFWalkToCureDiabetes.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=50a726b8-5918-4d49-864b-f8100851945d</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,50a726b8-5918-4d49-864b-f8100851945d.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,50a726b8-5918-4d49-864b-f8100851945d.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=50a726b8-5918-4d49-864b-f8100851945d</wfw:commentRss>
      <title>Binding to a List property with ASP.NET MVC</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,50a726b8-5918-4d49-864b-f8100851945d.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/GsOXBWWPWZ0/BindingToAListPropertyWithASPNETMVC.aspx</link>
      <pubDate>Wed, 23 Sep 2009 02:54:56 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;The model binders in ASP.NET MVC represent a fantastic example of &lt;a href="http://en.wikipedia.org/wiki/Convention_over_configuration"&gt;Coding by Convention&lt;/a&gt;. If you choose to abide by the naming rules, large amounts of work can be performed for you, but if you stray off of the path, you will have a lot of code to write. Let’s start with the simplest possible case, a model with a single property and a view with a single textbox for populating that property.&lt;/p&gt;  &lt;pre class="csharp" name="code"&gt;public class SimpleModel
{
  public string SimpleProperty { get; set; }
}&lt;/pre&gt;

&lt;p&gt;In order for a &lt;em&gt;Create&lt;/em&gt; view to bind to this property, all that is required is the name attribute of any input type (like textbox) match the name of the property in the model you intend to populate, in this case &lt;em&gt;SimpleProperty&lt;/em&gt;.&lt;/p&gt;

&lt;pre class="html" name="code"&gt;&amp;lt;input name=&amp;quot;SimpleProperty&amp;quot; /&amp;gt;&lt;/pre&gt;

&lt;p&gt;When the form is submitted, the &lt;em&gt;Create&lt;/em&gt; action on the &lt;em&gt;SimpleModelController&lt;/em&gt; is fired with a &lt;em&gt;SimpleModel&lt;/em&gt; object as a parameter. This object has the &lt;em&gt;SimpleProperty&lt;/em&gt; set with the value from the &amp;lt;input&amp;gt; with the same name. Pretty cool, but where is the massive amount of work being done for me?&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Nested Classes&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Now, lets make the model class a bit more interesting. This time, the model will be an outer class containing a nested class.&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public class OuterClass
{
  public string SomeProperty { get; set; }
  public NestedClass Nested { get; set; }
}

public class NestedClass
{
  public string SomeOtherProperty { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Now, if you use the Add View wizard, the resulting view will not contain any reference to the &lt;em&gt;NestedClass&lt;/em&gt;, but really who keeps those around anyway? (Until v2 when you can customize the template.) Just as in the previous sample, we need an &amp;lt;input&amp;gt; for each property that should be populated with values from the POST. &lt;em&gt;SomeProperty&lt;/em&gt; is the same case as the previous sample; &lt;em&gt;Nested&lt;/em&gt; and &lt;em&gt;SomeOtherProperty&lt;/em&gt; are slightly different. To understand the convention applied to this binding, think of how you would access &lt;em&gt;SomeOtherProperty&lt;/em&gt; from an instance of an &lt;em&gt;OuterClass&lt;/em&gt;. You would access the &lt;em&gt;outerClass.Nested.SomeOtherProperty&lt;/em&gt;, but remember &lt;em&gt;outerClass&lt;/em&gt; is our model and does not need to be named, so we are left with &lt;em&gt;Nested.SomeOtherProperty&lt;/em&gt;. &lt;/p&gt;

&lt;pre class="html" name="code"&gt;&amp;lt;input name=&amp;quot;SomeProperty&amp;quot;/&amp;gt; 
&amp;lt;input name=&amp;quot;Nested.SomeOtherProperty&amp;quot; /&amp;gt;&lt;/pre&gt;

&lt;p&gt;Again, when the form is submitted, the &lt;em&gt;Create&lt;/em&gt; action on the &lt;em&gt;OuterClassController&lt;/em&gt; will have a fully populated &lt;em&gt;OuterClass&lt;/em&gt; as a parameter including an instance of &lt;em&gt;NestedClass&lt;/em&gt; with &lt;em&gt;SomeOtherProperty&lt;/em&gt; set. Now, I am starting to get impressed. The techniques used to map controls to objects within WebForms, are starting to look pretty clunky. The default model binder is a powerful tool as long as you follow the naming rules.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Nested Lists&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;This next scenario is where it all clicked for me. I was trying to bind a dynamic list of objects to a property of my model. This is a simplified version of the scenario I was looking at:&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public class LogEntry 
{ 
  public int BloodSugar { get; set; } 
  public List&amp;lt;FoodEntry&amp;gt; FoodEntries { get; set; } 
} 

public class FoodEntry 
{ 
  public string Name { get; set; } 
  public string Carbs { get; set; } 
}&lt;/pre&gt;

&lt;p&gt;Just as with simple nested property, the default strongly-typed view creator will not add any UI elements for the nested class. That is fine; fewer lines of code for us to delete. To set up the view correctly, think of the description given in the last sample for the naming convention and the &lt;a href="http://en.wikipedia.org/wiki/Rule_of_least_surprise"&gt;Rule of Least Surprise&lt;/a&gt;. If you think of how to access each individual element of &lt;em&gt;FoodEntries&lt;/em&gt; you would have &lt;em&gt;FoodEntries[N].Name&lt;/em&gt; and &lt;em&gt;FoodEntries[N].Carbs&lt;/em&gt;. These are the names required of our input elements on the view.&lt;/p&gt;

&lt;pre class="html" name="code"&gt;&amp;lt;div class=&amp;quot;logEntry&amp;quot;&amp;gt; 
  &amp;lt;div class=&amp;quot;bloodSugarEntry&amp;quot;&amp;gt; 
    &amp;lt;label for=&amp;quot;BloodSugar&amp;quot;&amp;gt;BloodSugar:&amp;lt;/label&amp;gt; 
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;BloodSugar&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt; 
  &amp;lt;div class=&amp;quot;foodEntries&amp;quot;&amp;gt; 
    &amp;lt;div class=&amp;quot;foodEntry&amp;quot;&amp;gt; 
      &amp;lt;label for=&amp;quot;FoodEntries[0].Name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;
      &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;FoodEntries[0].Name&amp;quot; /&amp;gt; 
      &amp;lt;label for=&amp;quot;FoodEntries[0].Carbs&amp;quot;&amp;gt;Carbs:&amp;lt;/label&amp;gt;
      &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;FoodEntries[0].Carbs&amp;quot; /&amp;gt; 
    &amp;lt;/div&amp;gt; 
    &amp;lt;input type=&amp;quot;button&amp;quot; value=&amp;quot;Add More&amp;quot; name=&amp;quot;FoodEntries_AddMore&amp;quot; /&amp;gt; 
  &amp;lt;/div&amp;gt; 
  &amp;lt;div&amp;gt; 
    &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Log It!&amp;quot; /&amp;gt; 
  &amp;lt;/div&amp;gt; 
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;Now that there is some structure in the HTML that we can leverage, we can start adding some dynamic client side behavior. In this case, I want to be able to add more food items to the form without having to postback or even perform any AJAX requests. JQuery will be leveraged to inject more food entries into the DOM. The following code is added to the click event from the &lt;em&gt;FoodEntries_AddMore&lt;/em&gt; button.&lt;/p&gt;

&lt;pre class="javascript" name="code"&gt;$('#FoodEntries_More').click(function() { 
    var nextFoodEntryIndex = $('.foodEntry').size(); 
    var nextFoodEntryNamespace = 'FoodEntries[' + nextFoodEntryIndex + ']';

    var newFoodEntry = $('&amp;lt;div class=&amp;quot;foodEntry&amp;quot;&amp;gt;' + 
                         '&amp;lt;label for=&amp;quot;' + nextFoodEntryNamespace + '.Name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;' + 
                         '&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;' + nextFoodEntryNamespace + '_Name&amp;quot;' +
                         'name=&amp;quot;' + nextFoodEntryNamespace + '.Name&amp;quot; /&amp;gt;' + 
                         '&amp;lt;label for=&amp;quot;' + nextFoodEntryNamespace + '.Carbs&amp;quot;&amp;gt;Carbs:&amp;lt;/label&amp;gt;' + 
                         '&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;' + nextFoodEntryNamespace + '_Carbs&amp;quot;' +
                         'name=&amp;quot;' + nextFoodEntryNamespace + '.Carbs&amp;quot; /&amp;gt;' + 
                         '&amp;lt;/div&amp;gt;'); 

    $('.foodEntry:last').after(newFoodEntry); 
});&lt;/pre&gt;

&lt;p&gt;What this does is look at the set of food entries to determine how many are on the current page in order to determine the index used for the name on the next row of food entries. The first click will result in adding &lt;em&gt;FoodEntries[1].Name&lt;/em&gt; and &lt;em&gt;FoodEntries[1].Carbs&lt;/em&gt;. These names follow the naming convention that we established earlier. The default model binder recognizes this naming convention and populates the &lt;em&gt;LogEntry&lt;/em&gt; object with as many &lt;em&gt;FoodEntry&lt;/em&gt; items as have been created on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All of this auto-magic binding assumes that you are willing and able to follow the naming conventions necessary to have the default model binder do the work for you. If you are facing an exceptional situation where the default model binder will not work for you, use a FormCollection in the Create method and do all of the parsing yourself or create a custom model binder. As you can imagine, these tasks can become complicated and unreadable. So if at all possible, try to follow the path that does the work for you. It is worth noting that this is not at all like the drag and drop designers that have a habit of creating poor, hard-to-maintain code. All that is happening here is a form element to object mapping with the code on either end being as elegant as you like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where is the code?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code for this post can be found on GoogleCode at &lt;a title="http://dennisburton.googlecode.com/svn/trunk/PostSamples" href="http://dennisburton.googlecode.com/svn/trunk/PostSamples"&gt;http://dennisburton.googlecode.com/svn/trunk/PostSamples&lt;/a&gt;.&lt;/p&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=50a726b8-5918-4d49-864b-f8100851945d"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=GsOXBWWPWZ0:h9HVgdUFduM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/GsOXBWWPWZ0" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,50a726b8-5918-4d49-864b-f8100851945d.aspx</comments>
      <category>aspnetmvc</category>
      <category>jquery</category>
    <feedburner:origLink>http://developusing.net/2009/09/23/BindingToAListPropertyWithASPNETMVC.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=8c7fd586-6e53-411a-9956-91b19585601e</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,8c7fd586-6e53-411a-9956-91b19585601e.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,8c7fd586-6e53-411a-9956-91b19585601e.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=8c7fd586-6e53-411a-9956-91b19585601e</wfw:commentRss>
      <title>Conference Season is Here!</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,8c7fd586-6e53-411a-9956-91b19585601e.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/Q8NbdUYoarE/ConferenceSeasonIsHere.aspx</link>
      <pubDate>Wed, 20 May 2009 14:38:30 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;&lt;b&gt;Speaking at CodeStock 2009&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;This year &lt;a href="http://www.codestock.org/"&gt;CodeStock&lt;/a&gt; is shaping up to be a conference like no other. Most regional conferences have around 25 sessions with some attempt to do Open Spaces on the side. &lt;a href="http://www.codestock.org/"&gt;CodeStock 2009&lt;/a&gt; will certainly blow the doors off the norm with a community driven event with something to offer for everyone. To start with, it is the first conference that I know of that allowed the early registering attendees to choose the direction for the more than 50 hour-long &lt;a href="http://www.codestock.org/Sessions.aspx"&gt;sessions&lt;/a&gt; as well as 6 extended hands-on &lt;a href="http://www.codestock.org/Sessions.aspx"&gt;sessions&lt;/a&gt;. Then, to kick it up one more notch, &lt;a href="http://netcave.org/"&gt;Alan Stevens&lt;/a&gt; will be facilitating the Open Spaces. Make no mistake: Alan knows how to do Open Spaces right. Last year’s CodeStock was the moment the community took notice of the way that Alan’s particular talent set meshes with coordinating an exceptionally effective Open Space event. This is truly an event that has something to offer everyone.&lt;/p&gt;  &lt;p&gt;Given the community selection process, it is even more of an honor to be selected to speak at this event. I will be giving the PatternsInTesting presentation that has already been well received in the Midwest area.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Indy Code Camp 2009&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;I was privileged to be able to give the PatternsInTesting presentation at Indy Code Camp this year. There were many really good testing related conversations before and after the presentation. I am encouraged by the amount of interest the community is taking towards improving the adoption of test driven design. I also got to see a few top notch presentations:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.timwingfield.com/"&gt;Tim Wingfield&lt;/a&gt; - Care About Your Craft: A very motivating presentation on doing the right thing &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.japikse.blogspot.com/"&gt;Philip Japikse&lt;/a&gt; - CRUD Sucks! NHibernate to the rescue: Phil has an impressive in depth knowledge of NHibernate. I was most fascinated by all of the extensions that he has written to really make NHibernate hum. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jonfuller.codingtomusic.com/"&gt;Jon Fuller&lt;/a&gt; - Dealing with Dependencies: This was my favorite presentation of the day. Jon had only enough slides for an overview and went directly in to writing code. It was an in depth, working look at using DI tools. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://mjeaton.net/blog/"&gt;Michael Eaton&lt;/a&gt; - Developing Solid WPF Applications: A very informative view into a real world WPF application and its development evolution &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Greater Lansing .net User Group&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;A big thank you to &lt;a href="http://glugnet.org"&gt;GLUGnet&lt;/a&gt; for letting me do the PatternsInTesting presentation for the group. This is a group that I frequently attend, it is nice to be able to present on a topic that I talk about so much with the members of that group.&lt;/p&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=8c7fd586-6e53-411a-9956-91b19585601e"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=Q8NbdUYoarE:Ufr_uH7m48M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/Q8NbdUYoarE" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,8c7fd586-6e53-411a-9956-91b19585601e.aspx</comments>
    <feedburner:origLink>http://developusing.net/2009/05/20/ConferenceSeasonIsHere.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=6a0a4830-21e5-4012-a67a-51adcc156475</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,6a0a4830-21e5-4012-a67a-51adcc156475.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,6a0a4830-21e5-4012-a67a-51adcc156475.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=6a0a4830-21e5-4012-a67a-51adcc156475</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>PatternsInTesting[3] - Spy Pattern</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,6a0a4830-21e5-4012-a67a-51adcc156475.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/1o6KCXdTMnI/PatternsInTesting3SpyPattern.aspx</link>
      <pubDate>Tue, 19 May 2009 14:49:32 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;Your mission, should you choose to accept it, is to observe the interaction with an object and verify that this interaction is in your best interest. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Scenario&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Some objects that you have to consume are just poorly written. The ones that are most egregious always seem to be the ones you have no control over. That lack of control may be because you have no access to the source, it may be because it would be a political minefield to change the source, or a lack of tests makes the team afraid to change the source. It seems like every time I go to a new client, these objects exist (as well as the political minefields). The developers have a mysterious set of incantations that they have memorized for interaction with these objects in order to avoid bugs. Often, no one knows where these &amp;quot;rules&amp;quot; came from and they are usually not written down. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Vocabulary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The name of this pattern is the Spy. What the spy will do is capture information about interaction with an object, and only take action if the need arises. A spy object looks just like the object that you need to interact with (i.e. implements the same public interface) such that your code should not even notice it is even there, but, behind the scenes it will perform validation and give the useful feedback you wish the original object would have implemented in the first place. This spy or validation wrapper is commonly implemented by holding on to a reference to original object. This allows for the spy to call the actual implementation in order to preserve the original behavior. &lt;/p&gt;  &lt;blockquote&gt;   &lt;div&gt;     &lt;p&gt;&lt;strong&gt;The ideal world&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;In an ideal world, the kinds of interactions that you are trying to validate with a spy &lt;em&gt;should&lt;/em&gt; be captured be captured by the actual object you are interacting with, rather than the spy. Having a wrapper object whose function is validation is a massive code smell. If you have the ability to fix the original code by adding the relevant validation, that is by far a better solution than creating a spy object.&lt;/p&gt;      &lt;p&gt;&lt;strong&gt;The real world&lt;/strong&gt;&lt;/p&gt;      &lt;p&gt;In reality, you do not have access to change the source of third party libraries, even if sometimes that third party is a couple of buildings or even cubes away. The first thing you should do when you run in to these bizarre incantations “required” for successful object interaction, is to ask “why?” and be persistent, dig deep. You may be (not so) surprised that most of the reasons have long since &lt;a href="http://www.snopes.com/weddings/newlywed/secret.asp"&gt;gone away&lt;/a&gt;. If you do find that some of the hidden rules are indeed valid, you need a way to validate that your code is following the rules.&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Consider the following example where &lt;em&gt;MethodToObserve&lt;/em&gt; will throw an uninformitive exception if the &lt;em&gt;PropertyToObserve&lt;/em&gt; has not yet been set. &lt;/p&gt;  &lt;div style="font-family: consolas; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IInterfaceToUse&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;void&lt;/span&gt; MethodToObserve();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; PropertyToObserve { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ClassToUse&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IInterfaceToUse&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; MethodToObserve()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyToObserve.ForEach(str =&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Calling the MethodToObserve:&amp;quot;&lt;/span&gt; + str) );&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; propertyToObserve;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; PropertyToObserve&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine( &lt;span style="color: #a31515"&gt;&amp;quot;Calling the PropertyToObserve setter&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; propertyToObserve;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;set&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Calling the PropertyToObserve getter&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; propertyToObserve = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;As mentioned previously, the ideal solution is to fix the implementation. If your only access to this code is Reflector or you are just not authorized to change it, the next best thing is to protect yourself (flaming email to the author of the code is,of course, optional). Our protection, or at least better information will come from a class implementing &lt;em&gt;IInterfaceToUse&lt;/em&gt; just like the original, only this time the implementation will provide the consumer with information that they can act on.&lt;/p&gt;  &lt;div style="font-family: consolas; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ValidatingObserver&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IInterfaceToUse&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IInterfaceToUse&lt;/span&gt; _observedClass;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; ValidatingObserver(&lt;span style="color: #2b91af"&gt;IInterfaceToUse&lt;/span&gt; observedClass)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { _observedClass = observedClass; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; MethodToObserve()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (PropertyToObserve == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;PropertyToObserve&amp;quot;&lt;/span&gt;,&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #a31515"&gt;&amp;quot;Property must be set prior to calling Method&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// perform observations&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;The spy is watching: MethodToObserve&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// pass through to implementing object&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _observedClass.MethodToObserve();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; PropertyToObserve&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;The spy is watching: PropertyToObserve getter&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; _observedClass.PropertyToObserve;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;set&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;The spy is watching: PropertyToObserve setter&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _observedClass.PropertyToObserve = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Note that this time, instead of the “oops, I forgot something exception” known in .net as the “Object reference not set to instance of an object” exception, we get meaningful information about what is missing and even some hint as to how to fix it. The error now clearly states that the &lt;em&gt;PropertyToObserve&lt;/em&gt; should be set prior to calling the &lt;em&gt;MethodToObserve&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Using the spy&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There are many ways to create a spy object, I chose containment for this post; You may also use derivation to create your wrapper. Derivation will get you up and running faster, and you will not have maintenance work to do if you add a method to the interface, but this will come at a cost. Containment will allow you to swap out the actual implementation of the object with a mock implementation at some time in the future. As always consider you needs before choosing a spy implementation.&lt;/p&gt;  &lt;p&gt;The test below shows how to use the spy created in this post&lt;/p&gt;  &lt;div style="font-family: consolas; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt; [&lt;span style="color: #2b91af"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ManualObserverTests&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; MethodCallSpy()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; observedClass = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ClassToUse&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; validatingObserver = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ValidatingObserver&lt;/span&gt;(observedClass);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Throws&amp;lt;&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;&amp;gt;( validatingObserver.MethodToObserve);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;strong&gt;Tool Support&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All of the previous posts in this series have mentioned leveraging tools to assist in creating these test objects. They spy object however is a strange beast; the demands it places on the tools turn out to create as much code as the manually coded version. If you are so inclined, you can use Rhino for a spy object. What is required is taking advantage of the Do extension method. Do takes a delegate as a parameter that matches the signature of the method being called. So what you will end up establishing is an &lt;em&gt;Expect&lt;/em&gt;ation that a method will be called and when it is &lt;em&gt;Do&lt;/em&gt; the operation specified by the delegate. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The spy object reminds me of the &lt;a href="http://www.pragprog.com/the-pragmatic-programmer/extracts/software-entropy"&gt;Broken Windows&lt;/a&gt; section of the &lt;a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ref=sr_1_4?ie=UTF8&amp;amp;s=books&amp;amp;qid=1242740154&amp;amp;sr=8-4"&gt;Pragmatic Programmer&lt;/a&gt;. It clearly states not to live with broken windows, but if you cannot fix the window, at least put a board over the window. In the case of third party code where you cannot change the source code, a validation wrapper is the board you need to keep further damage from occurring and show other developers in the area that you still care about the quality of code.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;The Series&lt;/b&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting0Introduction.aspx"&gt;PatternsInTesting[0] - Introduction&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting1DummyPattern.aspx"&gt;PatternsInTesting[1] - Dummy Pattern&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;/div&gt; &lt;a href="http://developusing.net/2008/12/10/PatternsInTesting2StubPattern.aspx"&gt;PatternsInTesting[2] - Stub Pattern&lt;/a&gt;   &lt;div&gt;&lt;a href="http://developusing.net/2009/05/19/PatternsInTesting3SpyPattern.aspx"&gt;PatternsInTesting[3] - Spy Pattern&lt;/a&gt;&lt;/div&gt; PatternsInTesting[4] - Mock Pattern  &lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=6a0a4830-21e5-4012-a67a-51adcc156475"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=1o6KCXdTMnI:k6c8GzBlWKU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/1o6KCXdTMnI" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,6a0a4830-21e5-4012-a67a-51adcc156475.aspx</comments>
      <category>patterns</category>
      <category>programming</category>
      <category>testing</category>
    <feedburner:origLink>http://developusing.net/2009/05/19/PatternsInTesting3SpyPattern.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=c76e2c1e-2e64-42ce-bdf6-39f7aab0784a</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,c76e2c1e-2e64-42ce-bdf6-39f7aab0784a.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,c76e2c1e-2e64-42ce-bdf6-39f7aab0784a.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c76e2c1e-2e64-42ce-bdf6-39f7aab0784a</wfw:commentRss>
      <title>The MX Revolution is not a presentation mouse</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,c76e2c1e-2e64-42ce-bdf6-39f7aab0784a.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/-TammbBSkMg/TheMXRevolutionIsNotAPresentationMouse.aspx</link>
      <pubDate>Thu, 19 Mar 2009 23:20:16 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;&lt;a href="http://developusing.net/content/binary/WindowsLiveWriter/TheMXRevolutionisnotapresentationmouse_10F96/revolution_3_2.jpg"&gt;&lt;img title="revolution_3" style="border-right: 0px; border-top: 0px; display: inline; margin-left: 0px; border-left: 0px; margin-right: 0px; border-bottom: 0px" height="177" alt="revolution_3" src="http://developusing.net/content/binary/WindowsLiveWriter/TheMXRevolutionisnotapresentationmouse_10F96/revolution_3_thumb.jpg" width="142" align="right" border="0"&gt;&lt;/a&gt;I love my &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16826104015"&gt;MX Revolution&lt;/a&gt; mouse. It is the most comfortable mouse I have used to date. For me, this is the first mouse that the wireless works without glitches, the scroll wheel has virtually no resistance, and there are a pile of programmable features on well placed buttons. As a desktop mouse, I would suggest anyone give it a try.&lt;/p&gt; &lt;p&gt;As a presentation mouse, however, it did not work so well. The scroll wheel with no resistance would scroll under its own weight causing my slides to advance and back up in a very rapid fashion. This is a great example of a highly desired feature in one context being a complete hindrance in another. Now off I go to&amp;nbsp; find a device well suited for presentations. &lt;/p&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=c76e2c1e-2e64-42ce-bdf6-39f7aab0784a"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=-TammbBSkMg:o1YmZXx7LWQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/-TammbBSkMg" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,c76e2c1e-2e64-42ce-bdf6-39f7aab0784a.aspx</comments>
      <category>hardware</category>
    <feedburner:origLink>http://developusing.net/2009/03/19/TheMXRevolutionIsNotAPresentationMouse.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=9803fb00-0e05-4ad1-b5cb-147762ec5504</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,9803fb00-0e05-4ad1-b5cb-147762ec5504.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,9803fb00-0e05-4ad1-b5cb-147762ec5504.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9803fb00-0e05-4ad1-b5cb-147762ec5504</wfw:commentRss>
      <title>More Patterns in Testing</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,9803fb00-0e05-4ad1-b5cb-147762ec5504.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/XGduMhoydPI/MorePatternsInTesting.aspx</link>
      <pubDate>Mon, 16 Mar 2009 17:48:40 GMT</pubDate>
      <description>&lt;div&gt;I will be presenting items from the PatternsInTesting series as well as some additional content in the &lt;a href="http://developusing.net/2009/03/12/PatternsInTestingGoesLive.aspx"&gt;Test Driven is Driving me Insane&lt;/a&gt; talk at the &lt;a href="http://migang.org/MeetingInfo.aspx?CntProv=Events&amp;amp;CntItem=918abb85-b6f6-4208-a6f5-4340db63d2b3&amp;amp;ReturnURL=%2fMeetings.aspx&amp;amp;CntCatID=a0e23ee0-1ffe-4808-8aef-4316a2f458b0"&gt;Great Lakes .net User Group&lt;/a&gt; on 3/18/2009 and at the &lt;a href="http://www.nwnug.com/"&gt;Northwest Ohio .net User Group&lt;/a&gt; on 4/21/2009. This has been a really fun talk so far and I have enjoyed the conversation it generates. Stop by if you can make it.&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=9803fb00-0e05-4ad1-b5cb-147762ec5504"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=XGduMhoydPI:T-hAuPRW2MI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/XGduMhoydPI" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,9803fb00-0e05-4ad1-b5cb-147762ec5504.aspx</comments>
      <category>community</category>
      <category>patterns</category>
      <category>tdd</category>
      <category>testing</category>
    <feedburner:origLink>http://developusing.net/2009/03/16/MorePatternsInTesting.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=ea980c5a-24ab-4e03-92eb-00685ad0b38b</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,ea980c5a-24ab-4e03-92eb-00685ad0b38b.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,ea980c5a-24ab-4e03-92eb-00685ad0b38b.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ea980c5a-24ab-4e03-92eb-00685ad0b38b</wfw:commentRss>
      <title>Patterns in testing goes live</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,ea980c5a-24ab-4e03-92eb-00685ad0b38b.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/vwS3jvo_3Gs/PatternsInTestingGoesLive.aspx</link>
      <pubDate>Thu, 12 Mar 2009 13:15:15 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;I will be presenting items from the PatternsInTesting series&amp;nbsp;at the &lt;a href="http://glugnet.org"&gt;Greater 
Lansing .net User Group Flint &lt;/a&gt;meeting. I was compelled to put this blog series 
and presentation together to address the pain many organization experience when 
trying to include automated testing into their development process. The content 
is based on the insight and lessons learned that I have picked up by 
experiencing the same transition in multiple organizations. Participants in this 
presentation will walk away with tools for writing more effective tests and how 
to better identify issues in tests.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=ea980c5a-24ab-4e03-92eb-00685ad0b38b"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=vwS3jvo_3Gs:1DngyeCJZtc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/vwS3jvo_3Gs" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,ea980c5a-24ab-4e03-92eb-00685ad0b38b.aspx</comments>
      <category>community</category>
      <category>patterns</category>
      <category>tdd</category>
      <category>testing</category>
    <feedburner:origLink>http://developusing.net/2009/03/12/PatternsInTestingGoesLive.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=7a8184a8-d343-4b6e-9c8d-70b95e8e9ab5</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,7a8184a8-d343-4b6e-9c8d-70b95e8e9ab5.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,7a8184a8-d343-4b6e-9c8d-70b95e8e9ab5.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=7a8184a8-d343-4b6e-9c8d-70b95e8e9ab5</wfw:commentRss>
      <title>PatternsInTesting[2] - Stub Pattern</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,7a8184a8-d343-4b6e-9c8d-70b95e8e9ab5.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/6VgrK3DAMog/PatternsInTesting2StubPattern.aspx</link>
      <pubDate>Wed, 10 Dec 2008 22:49:06 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;&lt;strong&gt;The Scenario&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;On our continuing quest to create unit tests that exercise only the class under test, we look at another common scenario that occurs while writing tests. As with the &lt;i&gt;Dummy&lt;/i&gt;, our class under test has a dependency on another class, only this time the dependent class has an active role in our test. Our testing needs are about the logic of the class under test and not the interaction with the dependent object. In order to create a good test, the class under test must be isolated from the dependent object. &lt;/p&gt;  &lt;p&gt;An example of this scenario might look like this: &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ICalculator&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;int&lt;/span&gt; Add(&lt;span style="color: blue"&gt;int&lt;/span&gt; left, &lt;span style="color: blue"&gt;int&lt;/span&gt; right);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Fib&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ICalculator&lt;/span&gt; _calculator;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ICalculator&lt;/span&gt; Calculator&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; _calculator; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;set&lt;/span&gt; { _calculator = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; Next(&lt;span style="color: blue"&gt;int&lt;/span&gt; i, &lt;span style="color: blue"&gt;int&lt;/span&gt; j)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;span style="color: blue"&gt;return&lt;/span&gt; Calculator.Add(i,j); }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The class under test in this scenario is &lt;i&gt;Fib&lt;/i&gt;, which has a dependency on an &lt;i&gt;ICalculator&lt;/i&gt;. The test's objective is to validate that the &lt;i&gt;Next&lt;/i&gt; method returns the correct result for some well-known examples.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Vocabulary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The name of this pattern is the Stub. A stub stands in the place of the actual object in use and provides known answers and predictable behavior. If you are doing any sort of evolutionary development, chances are that the initial versions of your classes more resemble stubs then real code. Why? The goal is the same: you wrote stub functionality to allow you to focus your development efforts on different parts of the system. This is exactly what we are doing with Stub tests: isolate one part of the system from another by providing known results. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The solution without tools&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Unlike with a &lt;i&gt;Dummy&lt;/i&gt;, providing a class that throws a &lt;i&gt;NotImplementedExcpetion&lt;/i&gt; in the &lt;i&gt;Add&lt;/i&gt; method does not meet our needs. Since the functionality of &lt;i&gt;ICalculator&lt;/i&gt; is outside the scope of this test, we assume that it is working correctly (and hopefully under test). A simplistic implementation of &lt;i&gt;ICalculator &lt;/i&gt;will work nicely. Since we are not testing the calculator, provide a simplistic calculator that returns fixed results.&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 38&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; NextResultIsCorrect()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Fib&lt;/span&gt; fib = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Fib&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fib.Calculator = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StubCalculator&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 43&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 44&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(fib.Next(2, 3), &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.EqualTo(5));&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 45&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StubCalculator&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;ICalculator&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; Add(&lt;span style="color: blue"&gt;int&lt;/span&gt; left, &lt;span style="color: blue"&gt;int&lt;/span&gt; right)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;span style="color: blue"&gt;return&lt;/span&gt; 5; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The test will check that the &lt;i&gt;Next &lt;/i&gt;method returns the correct result given the &lt;i&gt;StubCalculator&lt;/i&gt;. What we end up doing here is fully exercising the &lt;i&gt;Fib &lt;/i&gt;class with known values from its dependent classes. The stub gives us the proper level of isolation for this test.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The solution with Rhino Mocks&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;For this version, leverage Rhino Mocks to keep us from having to code physical versions of the Stub class. Using Rhino's Fluent Interface, this reads as Expect a call on Calculator with the parameters 2 and 3, and when making this call return 5 as a result.&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 47&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 48&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; NextNumberIsCorrect()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 49&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 50&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Fib&lt;/span&gt; fib = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Fib&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 51&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fib.Calculator = &lt;span style="color: #2b91af"&gt;MockRepository&lt;/span&gt;.GenerateStub&amp;lt;&lt;span style="color: #2b91af"&gt;ICalculator&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 52&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fib.Calculator.Expect(calc =&amp;gt; calc.Add(2, 3)).Return(5);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 53&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 54&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(fib.Next(2, 3), &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.EqualTo(5));&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 55&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;strong&gt;The tools advantage&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Just as discussed with &lt;i&gt;IComplicated&lt;/i&gt; in the &lt;i&gt;Dummy &lt;/i&gt;sample, adding methods to &lt;i&gt;ICalculator&lt;/i&gt; does not require any additional maintenance of this test. However, unlike the &lt;i&gt;Dummy&lt;/i&gt; sample, calls into the stub return the expected value. Additional benefits can easily pile up. Consider adding multiple calls to &lt;i&gt;Add &lt;/i&gt;with different parameters. The hand-coded version would need some sort of conditional logic to determine what to return based on the calling parameters. Complexity adds up fast, even in the simple example listed here. Using Rhino, one concise and readable line of code can use new parameters for an additional expectation, including the expected result, and Rhino deals with matching up the parameters with the correct result. This is just a glimpse into the functionality offered by Rhino; the upcoming patterns will cover even more capability.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Isolation effects&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Should a test that checks the result of the &lt;i&gt;Next &lt;/i&gt;method fail if there is something wrong with the &lt;i&gt;ICalculator &lt;/i&gt;implementation? The answer, as always, is &amp;quot;it depends.&amp;quot; This test should fail if we were writing an integration test—a test that ensures all the pieces of a system are working together. This test should not fail based on &lt;i&gt;ICalculator &lt;/i&gt;if it is a unit test, focused only on the result of &lt;i&gt;Next&lt;/i&gt;. Isolating &lt;i&gt;ICalculator &lt;/i&gt;from &lt;i&gt;Fib &lt;/i&gt;helps build a set of unit tests that can quickly identify the location of errors introduced into a system. The stub is a common pattern of isolation, and using it will make a marked and immediate improvement in your tests.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;The Series&lt;/b&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting0Introduction.aspx"&gt;PatternsInTesting[0] - Introduction&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting1DummyPattern.aspx"&gt;PatternsInTesting[1] - Dummy Pattern&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/10/PatternsInTesting2StubPattern.aspx"&gt;PatternsInTesting[2] - Stub Pattern&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2009/05/19/PatternsInTesting3SpyPattern.aspx"&gt;PatternsInTesting[3] - Spy Pattern&lt;/a&gt;&lt;/div&gt; PatternsInTesting[4] - Mock Pattern  &lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=7a8184a8-d343-4b6e-9c8d-70b95e8e9ab5"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=6VgrK3DAMog:RS-pJPPeI24:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/6VgrK3DAMog" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,7a8184a8-d343-4b6e-9c8d-70b95e8e9ab5.aspx</comments>
      <category>patterns</category>
      <category>programming</category>
      <category>testing</category>
    <feedburner:origLink>http://developusing.net/2008/12/10/PatternsInTesting2StubPattern.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=21f508fe-a715-4d6c-8105-c58cd81b0a1f</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,21f508fe-a715-4d6c-8105-c58cd81b0a1f.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,21f508fe-a715-4d6c-8105-c58cd81b0a1f.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=21f508fe-a715-4d6c-8105-c58cd81b0a1f</wfw:commentRss>
      <title>PatternsInTesting[1] - Dummy Pattern</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,21f508fe-a715-4d6c-8105-c58cd81b0a1f.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/TCU3Vdc48I4/PatternsInTesting1DummyPattern.aspx</link>
      <pubDate>Thu, 04 Dec 2008 10:01:09 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;&lt;strong&gt;The Scenario&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One of the characteristics of a good &lt;i&gt;unit&lt;/i&gt; test is that the object under test is the only object being exercised. The problem in this scenario is that the object under test requires a dependent object, even though the functionality of the dependent object is not used in the test. To make a good test, the dependent object needs to be isolated from the class under test. &lt;/p&gt;  &lt;p&gt;An example of this scenario might look like this: &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;interface&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IAmComplicated&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;span style="color: blue"&gt;void&lt;/span&gt; DoStuff(); }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ClassUnderTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IAmComplicated&lt;/span&gt; complicated;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: rgb(43,145,175)"&gt;double&lt;/span&gt; circumference;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;#160;&lt;font color="#2b91af"&gt;double&lt;/font&gt; radius;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; ClassUnderTest(&lt;span style="color: rgb(43,145,175)"&gt;IAmComplicated&lt;/span&gt; externalComplicated)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt;( externalComplicated == &lt;span style="color: blue"&gt;null&lt;/span&gt; ) &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;complicated is required&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; complicated = externalComplicated; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;double&lt;/span&gt; DoInternalStuff() &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; circumference/(2*radius);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The dependency in &lt;i&gt;ClassUnderTest&lt;/i&gt; is that its constructor requires an instance of an object that implements &lt;i&gt;IAmComplicated&lt;/i&gt;.&lt;i&gt; &lt;/i&gt;The rather simple objective of this test is to validate that DoInternalStuff returns Pi within a reasonable amount of rounding error.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Vocabulary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The name of this pattern is the Dummy. It is unclear to me whether this is a reference to the object that enables isolation for the test or a reference to the original author of the code. It seems to be a code smell for this scenario to even occur. However, sometimes you need to use an external library and do not have liberty of changing the code.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The solution without tools&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Using only Visual Studio, add a class that implements &lt;i&gt;IAmComplicated&lt;/i&gt;, right-click on it, and choose implement interface. Every method in the class will throw a &lt;i&gt;NotImplementedException&lt;/i&gt;. This class meets the needs of the test because none of the methods are ever called; its only purpose is existence.This is your Dummy.&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComplicatedDummy&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;IAmComplicated&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DoStuff()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;NotImplementedException&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This Dummy class allows us to create the following test: &lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: rgb(43,145,175)"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;     &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DoStuffValidates()&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: rgb(43,145,175)"&gt;ClassUnderTest&lt;/span&gt; cut = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ClassUnderTest&lt;/span&gt;(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComplicatedDummy&lt;/span&gt;());&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 43&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cut.circumference = 314;&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 44&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cut.radius = 50;&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 45&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: rgb(43,145,175)"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: rgb(43,145,175)"&gt;Math&lt;/span&gt;.PI, cut.DoInternalStuff(), 0.01d);&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 46&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&lt;strong&gt;The solution with Rhino Mocks&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Rhino Mocks has the capability to create an object at runtime by reflecting the &lt;i&gt;IAmComplicated&lt;/i&gt; interface. This gives us the capability we need without having to maintain another class in the test project. Since Rhino is reflecting the interface at runtime, adding a method to the interface at a later date does not require changes to the test code. There are several different ways Rhino could give us a placeholder for &lt;i&gt;IAmComplicated&lt;/i&gt;. Here we will use a simple one line call to &lt;i&gt;GenerateStub&lt;/i&gt;.&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 55&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: rgb(43,145,175)"&gt;MockRepository&lt;/span&gt;.GenerateStub&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;IAmComplicated&lt;/span&gt;&amp;gt;();&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This one line saves us an entire file of maintenance, and our test only requires minor modification to use this technique. Place the call to Rhino as the parameter to the &lt;i&gt;ClassUnderTest&lt;/i&gt; constructor instead of creating a new &lt;i&gt;ComplicatedDummy&lt;/i&gt;.&lt;/p&gt;  &lt;div style="font-family: courier new; background: white; color: black; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 52&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: rgb(43,145,175)"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 53&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DoStuffValidates()&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 55&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: rgb(43,145,175)"&gt;ClassUnderTest&lt;/span&gt; cut = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ClassUnderTest&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;MockRepository&lt;/span&gt;.GenerateStub&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;IAmComplicated&lt;/span&gt;&amp;gt;());&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 56&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cut.circumference = 314;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 57&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cut.radius = 50;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 58&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: rgb(43,145,175)"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: rgb(43,145,175)"&gt;Math&lt;/span&gt;.PI, cut.DoInternalStuff(), 0.01d);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&amp;#160;&amp;#160; 59&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;strong&gt;Isolation of Failure&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One of the primary goals of good unit tests is to identify exactly which unit caused the error. By applying this pattern, tests that cover &lt;i&gt;ClassUnderTest&lt;/i&gt; no longer require an implementation of &lt;i&gt;IAmComplicated&lt;/i&gt; to instantiate without failure. This helps shorten your bug hunting cycle by reducing the areas that indicate error to where the real error occurred. As you attain higher levels of isolation and better definition of units, you will find you spend much less time in the debugger. This means spending less time finding problems more time fixing them.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;The Series&lt;/b&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting0Introduction.aspx"&gt;PatternsInTesting[0] - Introduction&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting1DummyPattern.aspx"&gt;PatternsInTesting[1] - Dummy Pattern&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;/div&gt; &lt;a href="http://developusing.net/2008/12/10/PatternsInTesting2StubPattern.aspx"&gt;PatternsInTesting[2] - Stub Pattern&lt;/a&gt;   &lt;div&gt;&lt;a href="http://developusing.net/2009/05/19/PatternsInTesting3SpyPattern.aspx"&gt;PatternsInTesting[3] - Spy Pattern&lt;/a&gt;&lt;/div&gt; PatternsInTesting[4] - Mock Pattern  &lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=21f508fe-a715-4d6c-8105-c58cd81b0a1f"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=TCU3Vdc48I4:icEsCPuVfrI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/TCU3Vdc48I4" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,21f508fe-a715-4d6c-8105-c58cd81b0a1f.aspx</comments>
      <category>patterns</category>
      <category>programming</category>
      <category>testing</category>
    <feedburner:origLink>http://developusing.net/2008/12/04/PatternsInTesting1DummyPattern.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=ba591026-21f9-451e-ae23-76d401194b36</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,ba591026-21f9-451e-ae23-76d401194b36.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,ba591026-21f9-451e-ae23-76d401194b36.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ba591026-21f9-451e-ae23-76d401194b36</wfw:commentRss>
      <title>PatternsInTesting[0] - Introduction</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,ba591026-21f9-451e-ae23-76d401194b36.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/pSXNn4Kg7bw/PatternsInTesting0Introduction.aspx</link>
      <pubDate>Thu, 04 Dec 2008 03:05:47 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;It does not matter if your test philosophy is Test Driven Development, Test Eventually Development, or I write tests occasionally. Very early in your testing experience, you will want to start isolating portions of your application or libraries. Without this isolation, you will start seeing a fragile set of tests that make it challenging to track down the point of failure. In order to reach the level of isolation that your tests need, you will need to introduce Mocks (or Test Doubles) to your testing toolbox.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Testing Story&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Someone on your team (extra geek cred if it was you) brings the concept of adding tests to the development process. No doubt there is some confusion at first. What are tests? How do we write them? This phase quickly passes as the team finds things that they understand how to test. This initial period of enlightenment yields great results. Everyone is happy that code is doing what it should be doing. Occasionally, the team celebrates when a broken test flags an unintended change. Clearly development will never be the same again. &lt;/p&gt;  &lt;p&gt;As time goes on and the test library gets larger, you start to notice that a breaking change often causes quite a few tests to fail. The team finds this annoying, but decides having tests is better than developer life before tests. At some point though, the tests start to feel burdensome. Adding simple changes start to propagate through the whole system of tests. Discouragement and discontentment set in, and some of your team members want to abandon developing with tests. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Enter Mocks&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;At this point, the prominent options are to ignore the tests (the blue pill) or find a way to make the tests better (the red pill). This series will cover some of the test development patterns used to isolate areas of your code in the hopes that you will choose the red pill. The goal for the initial four or five posts will be to cover the types of scenarios that occur in test code and what common solutions look like. After that, I hope to cover some of the patterns for dealing with legacy code as I am currently reading through Working Effectively with Legacy Code and it seems relevant to the client I am working with.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;The Mock Controversy&lt;/b&gt; &lt;/p&gt;  &lt;p&gt;There has been considerable conversation in the community about the usage of the term &lt;i&gt;mock&lt;/i&gt;. Some prominent members of the development community have been pushing for changing the vocabulary to &lt;i&gt;test doubles&lt;/i&gt;, where &lt;i&gt;mock&lt;/i&gt;, &lt;i&gt;stub&lt;/i&gt;, &lt;i&gt;fake&lt;/i&gt; and &lt;i&gt;spy&lt;/i&gt; are a particular type of &lt;i&gt;test double&lt;/i&gt;s. My take on this is that these &lt;i&gt;test double&lt;/i&gt; types are each describing the scenario where it is useful and the technique for solving the problem; this is describing a pattern. Good names are the key to effective patterns, and we have a good set of names for pattern description. It really does not matter what you call the concept (&lt;i&gt;mocking&lt;/i&gt; | &lt;i&gt;doubling&lt;/i&gt; | &lt;i&gt;faking | test doubles&lt;/i&gt;) if the pattern names describe the scenario effectively. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;What's next?&lt;/b&gt; &lt;/p&gt;  &lt;p&gt;This Series of posts will explore these test double patterns and decompose a few alternate implementations. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;The Series&lt;/b&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting0Introduction.aspx"&gt;PatternsInTesting[0] - Introduction&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/04/PatternsInTesting1DummyPattern.aspx"&gt;PatternsInTesting[1] - Dummy Pattern&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2008/12/10/PatternsInTesting2StubPattern.aspx"&gt;PatternsInTesting[2] - Stub Pattern&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;&lt;a href="http://developusing.net/2009/05/19/PatternsInTesting3SpyPattern.aspx"&gt;PatternsInTesting[3] - Spy Pattern&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;PatternsInTesting[4] - Mock Pattern&lt;/div&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=ba591026-21f9-451e-ae23-76d401194b36"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=pSXNn4Kg7bw:6lzpg2ejiAI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/pSXNn4Kg7bw" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,ba591026-21f9-451e-ae23-76d401194b36.aspx</comments>
      <category>patterns</category>
      <category>programming</category>
      <category>testing</category>
    <feedburner:origLink>http://developusing.net/2008/12/04/PatternsInTesting0Introduction.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://developusing.net/Trackback.aspx?guid=0cafcadb-b6e2-4259-82ff-b7d0f010fe92</trackback:ping>
      <pingback:server>http://developusing.net/pingback.aspx</pingback:server>
      <pingback:target>http://developusing.net/PermaLink,guid,0cafcadb-b6e2-4259-82ff-b7d0f010fe92.aspx</pingback:target>
      <dc:creator>Dennis Burton</dc:creator>
      <wfw:comment>http://developusing.net/CommentView,guid,0cafcadb-b6e2-4259-82ff-b7d0f010fe92.aspx</wfw:comment>
      <wfw:commentRss>http://developusing.net/SyndicationService.asmx/GetEntryCommentsRss?guid=0cafcadb-b6e2-4259-82ff-b7d0f010fe92</wfw:commentRss>
      <title>New features in NUnit 2.5</title>
      <guid isPermaLink="false">http://developusing.net/PermaLink,guid,0cafcadb-b6e2-4259-82ff-b7d0f010fe92.aspx</guid>
      <link>http://feedproxy.google.com/~r/DevelopUsingdotnet/~3/Hhx4C1MLU3Y/NewFeaturesInNUnit25.aspx</link>
      <pubDate>Mon, 17 Nov 2008 03:04:37 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;In my last &lt;a href="http://developusing.net/2008/11/03/HelpIHaveTooManyPermutationsToTest.aspx"&gt;post&lt;/a&gt;, I mentioned the new &lt;em&gt;ValuesAttribute&lt;/em&gt; that can be used as a test factory to generate a series of tests with many permutations of parameters. Looking into that feature led me to look at the feature set in &lt;a href="http://www.nunit.org/index.php?p=home"&gt;NUnit 2.5&lt;/a&gt; which is currently in Alpha 4. Some of these features address scenarios that I have run into in my test code. I wanted to mention them here so others could start benefiting as well.&lt;/p&gt; &lt;p&gt;The source of the new feature set that I am pulling from is the current &lt;a href="http://nunit.org/index.php?p=releaseNotes&amp;amp;r=2.5"&gt;release notes&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Movin' on up&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;One of the items that I think is most important &lt;strong&gt;is not&lt;/strong&gt; a new feature, just a change in location. The change in mind set is what stands out as important to me. The &lt;em&gt;Is&lt;/em&gt;, &lt;em&gt;Has&lt;/em&gt;, &lt;em&gt;Text&lt;/em&gt;, and &lt;em&gt;List&lt;/em&gt; constraints have been moved into the &lt;em&gt;NUnit.Framework&lt;/em&gt; namespace. They were formerly off in the more obscure &lt;em&gt;NUnit.Framework.SyntaxHelpers&lt;/em&gt; namespace. The assertions that are created using these constraints line up much better with BDD and have a more readable feel to them. I am happy to see them becoming part of the mainstream namespace. If you are not familiar with the constraint model, check out code below. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Classic model
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expected, actual);
&lt;span style="color: green"&gt;// Constraint model
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(actual, &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.EqualTo(expected));
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;I think the second reads much more like the English phrase that the constraint would represent. Check out the docs; you will find that almost everything you can do with the "classic" model can also be done in the constraint model.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chained Setup and TearDown&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Test code should be crafted with the same level of care as production intent code. This means that it should be DRY and carefully designed. Many times you will be testing a related set of classes, leading to base classes in your test code. Don't be afraid to capture common test code functionality in base classes. Prior to this release, the &lt;em&gt;Setup&lt;/em&gt; and &lt;em&gt;TearDown&lt;/em&gt; attributes could be applied in your base class, but if you applied the &lt;em&gt;Setup&lt;/em&gt; or &lt;em&gt;Teardown&lt;/em&gt; attributes in your derived class, the calls were not chained. You had to remember to call the base class version from the derived class. In 2.5, the base &lt;em&gt;Setup&lt;/em&gt; method will be call prior to the derived &lt;em&gt;Setup&lt;/em&gt; method by the framework. One more win for automation versus developer discipline. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;New constraints&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://srtsolutions.com/blogs/chrismarinos/"&gt;Chris Marinos&lt;/a&gt; recently &lt;a href="http://srtsolutions.com/blogs/chrismarinos/archive/2008/11/03/somebody-call-the-orkin-man.aspx"&gt;blogged&lt;/a&gt; about disliking the [ExpectedException] style of tests and wrote a helper class to support the syntax of &lt;em&gt;Throws.Exception&lt;/em&gt;. As of the 2.5 release &lt;em&gt;Throws.Exception&lt;/em&gt; is included. This allows for much more focused testing. Putting the &lt;em&gt;ExpectedExceptionAttribute&lt;/em&gt; on a method simply says that somewhere in the method the exception will get thrown. The exception may well be thrown 2 lines prior to the call you were intending to test. This yields a false positive test result. &lt;em&gt;Throws.Exception&lt;/em&gt; (and its set of related Throws) takes a delegate so that you can check a specific call for the presence of an exception. &lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]
[&lt;span style="color: #2b91af"&gt;ExpectedException&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;PassesButShouldnt()
{
    &lt;span style="color: blue"&gt;int &lt;/span&gt;importantPreWork = &lt;span style="color: blue"&gt;int&lt;/span&gt;.Parse(&lt;span style="color: #a31515"&gt;"abcd"&lt;/span&gt;);
    DoStuff();
}

[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;FailsProperly()
{
    &lt;span style="color: blue"&gt;int &lt;/span&gt;importantPreWork = &lt;span style="color: blue"&gt;int&lt;/span&gt;.Parse(&lt;span style="color: #a31515"&gt;"abcd"&lt;/span&gt;); 
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Throws&amp;lt;&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;&amp;gt;( DoStuff );
}
&lt;span style="color: blue"&gt;public void &lt;/span&gt;DoStuff()
{ &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Something is terribly wrong"&lt;/span&gt;); }
&lt;/pre&gt;
&lt;p&gt;In the example, the &lt;em&gt;PassesButShouldnt&lt;/em&gt; test passes due to the expected exception being thrown on the &lt;em&gt;Parse&lt;/em&gt; call. Unfortunately, the test was intended to ensure that &lt;em&gt;DoBadStuff&lt;/em&gt; threw an exception. The &lt;em&gt;FailsProperly&lt;/em&gt; test more accurately checks that only the &lt;em&gt;DoBadStuff&lt;/em&gt; call throws an exception. In addition, it also reads better as it places the constraint on the same line as the call just like any other &lt;em&gt;Assert&lt;/em&gt; method.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attribute testing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With the &lt;em&gt;Has.Attribute&lt;/em&gt; constraint, you can verify an object (yes, object not class) is decorated with an attribute. A common example of where this could be used is validating that a class has been marked with the &lt;em&gt;SerializableAttribute&lt;/em&gt;.&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;Serializable&lt;/span&gt;]
&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;testclass &lt;/span&gt;{}

[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;Test()
{ Assert.That(&lt;span style="color: blue"&gt;new &lt;/span&gt;testclass(), Has.Attribute&amp;lt;SerializableAttribute&amp;gt;()); }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;I have to admit, when I first saw the Has.Attribute constraint, I thought for sure one of my test base classes was going to get a bit lighter. One of the applications that I work on has a pluggable architecture and uses attributes to determine what should be exposed to the end user. I had to code up a method that used reflection to determine if the items that were supposed to be exposed did in fact contain the attribute that exposed them. I was somewhat disappointed to see that it only seemed to work with instances of objects and not &lt;em&gt;Type&lt;/em&gt;s or &lt;em&gt;MemberInfo&lt;/em&gt;s. This did get me thinking, however, that my approach of putting this in a base class may not have been as elegant as learning about extending NUnit. Perhaps that will be a post in the future. I should call out that this was in the NUnit blog as a feature added in Alpha 1, however, it is the only feature listed here that has not made it to the documentation yet. That could mean that it just has not been documented yet, or it could indicate that it is not yet ready for prime time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Range Testing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Is.InRange&lt;/em&gt; allows you to use a more concise syntax for expressing assertions that required both a &lt;em&gt;GreaterThan&lt;/em&gt; and &lt;em&gt;LessThan&lt;/em&gt; for validating an item is within bounds. &lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;Test&lt;/span&gt;]
&lt;span style="color: blue"&gt;public void &lt;/span&gt;RangeTesting()
{
    &lt;span style="color: green"&gt;// old way
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(3, &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.GreaterThanOrEqualTo(1) &amp;amp; &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.LessThanOrEqualTo(5));
    &lt;span style="color: green"&gt;// new way
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(3, &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.InRange(1, 5));

    &lt;span style="color: green"&gt;// NOTE: InRange is inclusive
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(5, &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.InRange(1, 5));
    &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.That(1, &lt;span style="color: #2b91af"&gt;Is&lt;/span&gt;.InRange(1, 5));
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;strong&gt;New Assertions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In some tests you are able to determine early in the test that the expected behavior has been met. Rather than throwing in a &lt;em&gt;return&lt;/em&gt; statement or creating triangular code, the new &lt;em&gt;Assert.Pass&lt;/em&gt; method is available for early termination with passing results. There is also a new inconclusive result state that can be set by calling &lt;em&gt;Assert.Inconclusive&lt;/em&gt;. I have no idea how this can be used; I cannot think of any test scenarios that I have had to implement where I really was looking for "Assert...oh...I don't know." It seems there is a failure in the system at this point, even if that failure point is not understanding the requirements. I would take this as an indicator to go clarify requirements with the client and write a better test.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Specialized Assertions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;CollectionAssert&lt;/em&gt; has picked up a set of &lt;em&gt;IsOrdered&lt;/em&gt; constraints. This constraint uses the &lt;em&gt;IComparable&lt;/em&gt; interface to verify increasing or decreasing order of all of the items in a collection. This is another one of those features that I have implemented in a test utilities class. I am happy to remove those lines of code.&lt;/p&gt;
&lt;p&gt;Previous versions of NUnit had a &lt;em&gt;FileAssert&lt;/em&gt; class to verify that your application was generating an output file. &lt;em&gt;DirectoryAssert&lt;/em&gt; has been added as a compliment to &lt;em&gt;FileAssert&lt;/em&gt;. The &lt;em&gt;DirectoryAssert.IsWithin&lt;/em&gt; method (or &lt;em&gt;IsNotWithin&lt;/em&gt;) will crawl from the directory specified, including all of its subdirectories, to verify that the expected directory is present. You can also use &lt;em&gt;IsEmpty&lt;/em&gt; to verify if a file was output. You are, of course, still responsible for determining that the correct output was written.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generic Support&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are several type constraints in NUnit that take &lt;em&gt;typeof(class)&lt;/em&gt; as a parameter. The following constraints have been updated to include a version that takes a generic parameter specifying the type.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsInstanceOf&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;object &lt;/span&gt;actual);
&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotInstanceOf&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;object &lt;/span&gt;actual);
&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsAssignableFrom&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;object &lt;/span&gt;actual);
&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotAssignableFrom&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;object &lt;/span&gt;actual);
&lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Throws&amp;lt;T&amp;gt;(TypeSnippet code);
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The &lt;em&gt;TestFixtureAttribute&lt;/em&gt; also picked up a generic version. Use this to test a class that takes a generic type parameter. Specify this attribute multiple times on a class, each time specifying a different type for the generic parameter. For each type specification, a new test instance is created and executed. This is useful when you were trying to exercise a class under test with a couple of different types. It does seem like this is the wrong level of abstraction for a test, but I am sure it is a reaction to some level of demand.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Try it out&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Every one has a different tolerance for using things that have not been marked as released, yet. Early releases of NUnit traditionally have been very solid. Much like GMail still being in beta, it seems the open source community drop releases much more often, but keeps them flagged with alpha and beta. I have already started using these features to produce cleaner, more readable test code.&lt;/p&gt;&lt;img width="0" height="0" src="http://developusing.net/aggbug.ashx?id=0cafcadb-b6e2-4259-82ff-b7d0f010fe92"/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?a=Hhx4C1MLU3Y:x8fPgZ4xWfk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopUsingdotnet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopUsingdotnet/~4/Hhx4C1MLU3Y" height="1" width="1"/&gt;</description>
      <comments>http://developusing.net/CommentView,guid,0cafcadb-b6e2-4259-82ff-b7d0f010fe92.aspx</comments>
      <category>tdd</category>
    <feedburner:origLink>http://developusing.net/2008/11/17/NewFeaturesInNUnit25.aspx</feedburner:origLink></item>
  </channel>
</rss>
