<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>TheHumbleProgrammer</title>
	<atom:link href="http://thehumbleprogrammer.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://thehumbleprogrammer.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Fri, 10 Jul 2009 13:15:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='thehumbleprogrammer.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>TheHumbleProgrammer</title>
		<link>http://thehumbleprogrammer.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://thehumbleprogrammer.wordpress.com/osd.xml" title="TheHumbleProgrammer" />
	<atom:link rel='hub' href='http://thehumbleprogrammer.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Keep on tweaking &#8211; solution</title>
		<link>http://thehumbleprogrammer.wordpress.com/2009/07/10/keep-on-tweaking-solution/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2009/07/10/keep-on-tweaking-solution/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 13:15:05 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/2009/07/10/keep-on-tweaking-solution/</guid>
		<description><![CDATA[in my previous post I published the following code 1: public void SetCustomerPropertiesOnView(IEnumerable&#60;Customer&#62; customers) 2: { 3: int count = 1; 4: string previousSurname = string.Empty; 5: foreach (var customer in customers) 6: { 7: this.View.AllCustomers.Add(new CustomerDisplay(customer)); 8:&#160; 9: if (count == 1) 10: previousSurname = customer.Surname; 11:&#160; 12: if (customer.Surname != previousSurname) 13: { [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=77&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>in my <a href="http://thehumbleprogrammer.wordpress.com/2009/07/03/keep-on-tweaking/">previous post</a> I published the following code</p>
<div>
<div style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;padding:0;">
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   1:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SetCustomerPropertiesOnView(IEnumerable&lt;Customer&gt; customers)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   2:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   3:</span>     <span style="color:#0000ff;">int</span> count = 1;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   4:</span>     <span style="color:#0000ff;">string</span> previousSurname = <span style="color:#0000ff;">string</span>.Empty;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   5:</span>     <span style="color:#0000ff;">foreach</span> (var customer <span style="color:#0000ff;">in</span> customers)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   6:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   7:</span>         <span style="color:#0000ff;">this</span>.View.AllCustomers.Add(<span style="color:#0000ff;">new</span> CustomerDisplay(customer));</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   8:</span>&nbsp; </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   9:</span>         <span style="color:#0000ff;">if</span> (count == 1)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  10:</span>             previousSurname = customer.Surname;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  11:</span>&nbsp; </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  12:</span>         <span style="color:#0000ff;">if</span> (customer.Surname != previousSurname)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  13:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  14:</span>             <span style="color:#0000ff;">this</span>.View.SurnameFilter.Add(<span style="color:#0000ff;">new</span> NorthWindListItem(customer.Surname, customer.ID.ToString()));</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  15:</span>             previousSurname = customer.Surname;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  16:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  17:</span>         count++;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  18:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  19:</span> }</pre>
</div>
</div>
<p>The context around this code is a view that shows all customers and allows the user to filter on surnames. Therefore I go and get the customers from the database I transform them for display and extract the unique surnames for the filtering functionality. I want to do all of this in one iteration of the customer list. </p>
<p>The above code achieves this aim, it may well be a naive implementation and there are other ways of doing this in a more efficient manner. That said the point of this post is to focus on the maintainability of this implementation, not it&#8217;s efficiency or approach. I would say that most developers would probably leave this implementation as is once they have achieved the goal. They would probably not be inclined to refactor this working solution into a more elegant solution that is maintainable over time. </p>
<p>My end solution to this problem looks like this</p>
<div>
<div style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;padding:0;">
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   1:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SetCustomerPropertiesOnView(IEnumerable&lt;Customer&gt; customers)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   2:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   3:</span>     var customersAndSurnames = customers.TransformForDisplay().AndGetDistinctSurnames();</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   4:</span>&nbsp; </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   5:</span>     <span style="color:#0000ff;">this</span>.View.AllCustomers = <span style="color:#0000ff;">this</span>.GetCustomersFrom(customersAndSurnames);</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   6:</span>     <span style="color:#0000ff;">this</span>.View.Surnames = <span style="color:#0000ff;">this</span>.GetUniqueSurnamesFrom(customersAndSurnames);</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   7:</span> }</pre>
</div>
</div>
<p>The implementation of the two extension methods is not really that important in the end we still have the horrible implementation, but at the top level when the next guy comes along to add or maintain this code they will have some context around what we are trying to do. SetCustomerPropertiesOnView now has a more declarative style, you can see straight away that we are transforming customers for display and getting distinct surnames in order to give them to the view. The two private methods are just wrappers around extraction of the values in a C# implementation of a <a href="http://en.wikipedia.org/wiki/Tuple">tuple</a>, which is used to return two different types of values from one method without using out or ref parameters. </p>
<p>In conclusion once you have found a solution that works don&#8217;t just stop there, use the tests too aid your refactoring of a first attempt into a more maintainable elegant intention revealing block of code. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/77/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=77&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2009/07/10/keep-on-tweaking-solution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>
	</item>
		<item>
		<title>Keep On Tweaking</title>
		<link>http://thehumbleprogrammer.wordpress.com/2009/07/03/keep-on-tweaking/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2009/07/03/keep-on-tweaking/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 08:55:24 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Quality]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/2009/07/03/keep-on-tweaking/</guid>
		<description><![CDATA[What does this piece of code do? 1: public void SetCustomerPropertiesOnView(IEnumerable&#60;Customer&#62; customers) 2: { 3: int count = 1; 4: var previousSurname = string.Empty; 5: foreach (var customer in customers) 6: { 7: this.View.AllCustomers.Add(new CustomerDisplay(customer)); 8:&#160; 9: if (count == 1) 10: previousSurname = customer.Surname; 11:&#160; 12: if (customer.Surname != previousSurname) 13: { 14: this.View.SurnameFilter.Add(new [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=74&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>What does this piece of code do?</p>
<div style="border-right:gray 1px solid;border-top:gray 1px solid;font-size:10pt;overflow:auto;width:97.06%;cursor:text;line-height:12pt;border-bottom:gray 1px solid;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;padding:4px;">
<div style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;padding:0;">
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   1:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SetCustomerPropertiesOnView(IEnumerable&lt;Customer&gt; customers)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   2:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   3:</span>     <span style="color:#0000ff;">int</span> count = 1;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   4:</span>     var previousSurname = <span style="color:#0000ff;">string</span>.Empty;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   5:</span>     <span style="color:#0000ff;">foreach</span> (var customer <span style="color:#0000ff;">in</span> customers)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   6:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   7:</span>         <span style="color:#0000ff;">this</span>.View.AllCustomers.Add(<span style="color:#0000ff;">new</span> CustomerDisplay(customer));</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   8:</span>&nbsp; </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   9:</span>         <span style="color:#0000ff;">if</span> (count == 1)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  10:</span>             previousSurname = customer.Surname;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  11:</span>&nbsp; </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  12:</span>         <span style="color:#0000ff;">if</span> (customer.Surname != previousSurname)</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  13:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  14:</span>             <span style="color:#0000ff;">this</span>.View.SurnameFilter.Add(<span style="color:#0000ff;">new</span> NorthWindListItem(customer.Surname, customer.ID.ToString()));</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  15:</span>             previousSurname = customer.Surname;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  16:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  17:</span>         count++;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  18:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  19:</span> }</pre>
</div>
</div>
<p>&nbsp;</p>
<p>I will explain the reasons behind this code, and come up with a more refined solution in a later post. More often than not we come across implementations like this where the maintainer has to work really hard to get to the intent of the code.&nbsp; In short this is an example of working code that is not easily maintainable over time, we can and should do better. With the safety net of unit tests I can now play around with this code to make it better.</p>
<p>This all goes back to Mike Waggs post on <a href="http://mikewagg.blogspot.com/2009/06/why-i-love-tddbdd.html">why he loves TDD/BDD</a> particularly when he talks about tweaking code</p>
<blockquote>
<p>&#8220;The best developers are those that continuously refine their code. They take something that is just a solution to the problem at hand and transform it into something which is clean and elegant. They craft a piece of code that is easily understandable by other developers and which can be easily maintained as the requirements of the system changes.&#8221;</p>
</blockquote>
<p>I couldn&#8217;t agree more with this sentiment. The code above is a practical example of why we should strive to keep on tweaking. As I said before the code works, it does a job, should I walk away happy with this implementation. Absolutely not, we can make it better, so that the next person that has to delve into this code will get more understanding from reading it, not more questions.</p>
<p>Trying to understand this implementation will take time, to the business time is money and developer time is even more money. So for the good of the business don&#8217;t lock in your ignorance by leaving a first attempt at a solution to a problem, tweak it, until it clearly expresses your intent. </p>
<p>My solution will follow&#8230;what&#8217;s yours?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/74/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=74&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2009/07/03/keep-on-tweaking/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>
	</item>
		<item>
		<title>Given you&#8217;ve heard of BDD, When you try to get started, Then you will find much confusion and anger.</title>
		<link>http://thehumbleprogrammer.wordpress.com/2009/04/18/given-youve-heard-of-bdd-when-you-try-to-get-started-then-you-will-find-much-confusion-and-anger/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2009/04/18/given-youve-heard-of-bdd-when-you-try-to-get-started-then-you-will-find-much-confusion-and-anger/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 16:41:37 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[BDD]]></category>
		<category><![CDATA[Unit testing]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/?p=67</guid>
		<description><![CDATA[On my last project, as part of a developer wide shift I was introduced to Behaviour Driven Development. BDD has been gathering interest in the test driven community for quite some time. For a good background to this development technique it&#8217;s best to start at the beginning and  read Dan North&#8217;s article introducing BDD. From [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=67&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>On my last project, as part of a developer wide shift I was introduced to Behaviour Driven Development. BDD has been gathering interest in the test driven community for quite some time. For a good background to this development technique it&#8217;s best to start at the beginning and  read Dan North&#8217;s article <a href="http://dannorth.net/introducing-bdd">introducing BDD</a>. From this article you can see the intention of BDD is to simplify a test first approach to software development,</p>
<blockquote><p><em>I had a problem. While using and teaching agile practices like test-driven development (TDD) on projects in different environments, I kept coming across the same confusion and misunderstandings. Programmers wanted to know where to start, what to test and what not to test, how much to test in one go, what to call their tests, and how to understand why a test fails.</em></p>
<p>The deeper I got into TDD, the more I felt that my own journey had been less of a wax-on, wax-off process of gradual mastery than a series of blind alleys. I remember thinking “If only someone had told me that!” far more often than I thought “Wow, a door has opened.” I decided it must be possible to present TDD in a way that gets straight to the good stuff and avoids all the pitfalls.</p>
<p>My response is behaviour-driven development (BDD). It has evolved out of established agile practices and is designed to make them more accessible and effective for teams new to agile software delivery. Over time, BDD has grown to encompass the wider picture of agile analysis and automated acceptance testing.</p></blockquote>
<p>thus lowering the entry level, which will increase take up amongst developers and the quality bar will be increased. Once you have read the article and, like me, felt an overwhelming desire to make the jump from boring old TDD to brand new BDD immediately, you will then mistakenly Google a phrase such as &#8220;<a href="http://www.google.co.uk/search?rlz=1C1GGLS_en-GBGB291GB305&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=Getting+Started+With+BDD">Getting Started With BDD</a>&#8220;. Ignoring the Microsoft articles you will avidly read anything and everything in this search result trying to grok BDD, unfortunately all you will find my friend, is confusion and anger.</p>
<p>In the end you must resist the urge to download any of the BDD frameworks out there until you have gotten your hands dirty writing your own implementation of BDD. Once you have become comfortable with this, by all means move onto a framework that allows you to bake the user stories into the tests rendering them unreadable at a glance etc. It&#8217;s your choice, we live in a democracy.</p>
<h2>Getting started with BDD the pain free way.</h2>
<p>first go to Ben Scheirman&#8217;s excellent article <a href="http://flux88.com/blog/the-transition-from-tdd-to-bdd/">outlining the Transition from TDD to BDD</a>, this will give you a clear grounding in making the move. Then have a play around with subclassing Ben&#8217;s base class and implementing some BDD test fixtures. <a href="http://timross.wordpress.com/">Tim</a> and <a href="http://mikewagg.blogspot.com/">Mike</a> did this in my last company resulting in a nice simple framework that could be rolled out across the developer team with a minimal learning curve. The minimal learning curve is very important if you want take up of BDD, which is what the framework writers have forgotten in trying to cleverly bake trace ability from stories too behaviour into the test suite.</p>
<p>An example of our version of BDD would look like this:</p>
<div style="font-size:8pt;overflow:auto;width:97.5%;cursor:text;max-height:450px;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border:gray 1px solid;margin:20px 0 10px;padding:4px;">
<div style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;padding:0;">
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   1:</span> <span style="color:#0000ff;">namespace</span> specs_for_SessionManager</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   2:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   3:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">class</span> SessionManager_base_context : Specification&lt;SessionManager&gt;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   4:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   5:</span>         <span style="color:#0000ff;">protected</span> Mock&lt;ISession&gt; Session { get; <span style="color:#0000ff;">private</span> set; }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   6:</span>         <span style="color:#0000ff;">protected</span> String SessionName { get; <span style="color:#0000ff;">private</span> set; }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   7:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   8:</span>         <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> EstablishContext()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   9:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  10:</span>             Session = <span style="color:#0000ff;">base</span>.Substitute&lt;ISession&gt;();</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  11:</span>             Session.Setup(s =&gt; s.Close());</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  12:</span>             Session.Setup(s =&gt; s.BeginTransaction()).Returns(<span style="color:#0000ff;">base</span>.Substitute&lt;ITransaction&gt;().Object);</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  13:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  14:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  15:</span>         <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> SessionManager CreateSubject()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  16:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  17:</span>             <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> SessionManager(Session.Object, SessionName);</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  18:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  19:</span>     }</pre>
</div>
</div>
<p>Here I have my specifications for the SessionManager, I then subclass Bens base class and override the necessary methods to establish a context and create the system under test. I can then go on to create a scenario for different behaviours of the system.</p>
<div style="font-size:8pt;overflow:auto;width:97.5%;cursor:text;max-height:450px;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border:gray 1px solid;margin:20px 0 10px;padding:4px;">
<div style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;padding:0;">
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   1:</span> [TestFixture]</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   2:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> when_closing_a_session : SessionManager_base_context</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   3:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   4:</span>     <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> When()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   5:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   6:</span>         <span style="color:#0000ff;">base</span>.Subject.CloseSession();</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   7:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   8:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   9:</span>     [Test]</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  10:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> underlying_session_should_be_called()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  11:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  12:</span>         Session.AssertWasCalled(s =&gt; s.Close());</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  13:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  14:</span> }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  15:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  16:</span> [TestFixture]</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  17:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> when_beginning_a_transaction : SessionManager_base_context</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  18:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  19:</span>     <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> When()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  20:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  21:</span>         <span style="color:#0000ff;">base</span>.Subject.BeginTransaction();</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  22:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  23:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  24:</span>     [Test]</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  25:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> a_transaction_should_have_begun_on_the_underlying_session()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  26:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  27:</span>         Session.AssertWasCalled(s =&gt; s.BeginTransaction());</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  28:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  29:</span> }</pre>
</div>
</div>
<p>As you can see we have a test fixture for each scenario, which overrides the when method in order to invoke the system under test in this context. Each test makes some assertion for expected behaviour in this scenario. Note the tests are now just one line assertions, we have split out the arrange and act part of the tests into the base class and the When method. The outcome of all this is a nice report in your resharper test runner like so;</p>
<p><a href="http://thehumbleprogrammer.files.wordpress.com/2009/04/notquiteright-bdd.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://thehumbleprogrammer.files.wordpress.com/2009/04/notquiteright-bdd-thumb.jpg?w=643&#038;h=190" border="0" alt="NotQuiteRight_BDD" width="643" height="190" /></a></p>
<p>This is a big step in the right direction, we can see the scenario that we are testing and the outcome of that behaviour being invoked, the only thing we are missing is the given. With the current style I found myself tacking on some context to the class name like so</p>
<blockquote><p><strong>when_beginning_a_transaction_with_a_pre_existing_transaction</strong></p></blockquote>
<p>This is not quite right, in my code I want to say <em>Given a transaction is running When beginning a transaction Then an exception should be thrown</em>, I can&#8217;t easily do that with the current structure so I tried using the namespace for the given and now my structure looks like this:</p>
<div style="font-size:8pt;overflow:auto;width:97.5%;cursor:text;max-height:450px;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border:gray 1px solid;margin:20px 0 10px;padding:4px;">
<div style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;padding:0;">
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   1:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   2:</span> <span style="color:#0000ff;">namespace</span> base_context_for</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   3:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   4:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">class</span> session_manager : Specification&lt;SessionManager&gt;</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   5:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   6:</span>         <span style="color:#0000ff;">protected</span> Mock&lt;ISession&gt; Session { get; <span style="color:#0000ff;">private</span> set; }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   7:</span>         <span style="color:#0000ff;">protected</span> Mock&lt;ITransaction&gt; Transaction { get; <span style="color:#0000ff;">private</span> set; }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   8:</span>         <span style="color:#0000ff;">protected</span> String SessionName { get; <span style="color:#0000ff;">private</span> set; }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">   9:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  10:</span>         <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> EstablishContext()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  11:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  12:</span>             Session = <span style="color:#0000ff;">base</span>.Substitute&lt;ISession&gt;();</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  13:</span>             Transaction = <span style="color:#0000ff;">base</span>.Substitute&lt;ITransaction&gt;();</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  14:</span>             Session.Setup(s =&gt; s.Close());</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  15:</span>             Session.Setup(s =&gt; s.BeginTransaction()).Returns(Transaction.Object);</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  16:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  17:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  18:</span>         <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> SessionManager CreateSubject()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  19:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  20:</span>             <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> SessionManager(Session.Object, SessionName);</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  21:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  22:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  23:</span> }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  24:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  25:</span> <span style="color:#0000ff;">namespace</span> given_a_session_is_open</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  26:</span> {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  27:</span>     [TestFixture]</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  28:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> when_closing_a_session : base_context_for.session_manager</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  29:</span>     {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  30:</span>         <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> When()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  31:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  32:</span>             <span style="color:#0000ff;">base</span>.Subject.CloseSession();</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  33:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  34:</span> </pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  35:</span>         [Test]</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  36:</span>         <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> underlying_session_should_be_closed()</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  37:</span>         {</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  38:</span>             Session.AssertWasCalled(s =&gt; s.Close());</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  39:</span>         }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  40:</span>     }</pre>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:white;border-style:none;margin:0;padding:0;"><span style="color:#606060;">  41:</span> }</pre>
</div>
</div>
<p>As you can see my base context is now in its own namespace called base_context_for, the base context class name is just the system under test. I can then subclass the base class with a fully qualified name, like so;</p>
<p><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> when_closing_a_session : base_context_for.session_manager</p>
<p>The above signature makes it really easy to see exactly what the system under test is and what the scenario is. </p>
<p>On line 25 you will see that I have another namespace declaration to wrap the subclass, the namespace becomes the given, the class name is the when and the test methods correspond to then. Giving a nice resharper report like this:</p>
<p><a href="http://thehumbleprogrammer.files.wordpress.com/2009/04/final-bdd.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://thehumbleprogrammer.files.wordpress.com/2009/04/final-bdd-thumb.jpg?w=661&#038;h=212" border="0" alt="final_bdd" width="661" height="212" /></a></p>
<p>For those of us that like to run TestDriven.Net, we will still get the same output when all is good</p>
<p>5 passed, 0 failed, 0 skipped, took 2.33 seconds.</p>
<p>but if you get a failing test you get the following output:</p>
<p><strong>TestCase &#8216;given_a_transaction_already_exists.when_beginning_a_transaction.should_throw_invalid_operation_exception&#8217;</strong></p>
<p><strong> failed:<br />
  Expected: instance of &lt;System.InvalidOperationException&gt;<br />
  But was:  null</strong></p>
<p>you can clearly see on the top line a full scenario description, which should make it nice and easy to figure out exactly what the issue is.</p>
<h2>Conclusion</h2>
<p>It is still early days for me and BDD but I am enjoying it and can see the benefit. For me BDD is all about giving an intuitive entry point into test first development, a by product of this is a nice report that developers can quickly see what is going wrong in their system under certain conditions. I think that trying to bake the full user story into the system at all levels of testing is a recipe for disaster. The frameworks for BDD seem to be geared towards the being able to trace a user story to some behaviour in your system. This leads to confusion for the developer, long overly noisy tests peppered with unmaintainable strings. The transition is now complete from TDD to BDD, until I have more experience in writing Behaviour fixtures I will stick to this structure. I would love to hear any of your thoughts (not you mum, my other reader, cheers big bro) on this structure and how it can be improved.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=67&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2009/04/18/given-youve-heard-of-bdd-when-you-try-to-get-started-then-you-will-find-much-confusion-and-anger/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>

		<media:content url="http://thehumbleprogrammer.files.wordpress.com/2009/04/notquiteright-bdd-thumb.jpg" medium="image">
			<media:title type="html">NotQuiteRight_BDD</media:title>
		</media:content>

		<media:content url="http://thehumbleprogrammer.files.wordpress.com/2009/04/final-bdd-thumb.jpg" medium="image">
			<media:title type="html">final_bdd</media:title>
		</media:content>
	</item>
		<item>
		<title>Leap of faith</title>
		<link>http://thehumbleprogrammer.wordpress.com/2008/12/16/leap-of-faith/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2008/12/16/leap-of-faith/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 06:31:05 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Working practices]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/?p=60</guid>
		<description><![CDATA[Over the past couple of months I have taken the plunge and decided to go into the murky world of short term contracting (hence why the blog has been so quiet of late). With my current experience most companies want me to move up the ladder to senior dev roles. Whilst I feel that this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=60&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Over the past couple of months I have taken the plunge and decided to go into the murky world of short term contracting (hence why the blog has been so quiet of late). With my current experience most companies want me to move up the ladder to senior dev roles. Whilst I feel that this is ultimately a good thing I feel that I need to learn a hell of a lot more about software development before I can begin to lead a team and mentor junior devs on the job. Moving up the ladder, being in a position of influence is something that I take very seriously. I feel that too many companies/devs are too eager to move up the ladder without having gained enough real experience with different projects in different problem domains.</p>
<p>I have been really spoilt by my first contract as the client I am working with does a lot of the Agile practices I have been looking for. The upper management believe and back these Agile practices such as close customer contact, TDD and continuous integration. In general the output from this team of developers is very stable with few issues coming back once released. Working for this client has convinced me more than ever that good Agile practices are the way to go when authoring Business software.</p>
<p>More on this later&#8230;for now I got work to do&#8230; </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=60&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2008/12/16/leap-of-faith/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>
	</item>
		<item>
		<title>Mock Object Frameworks Part 3</title>
		<link>http://thehumbleprogrammer.wordpress.com/2008/09/23/mock-object-frameworks-part-3/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2008/09/23/mock-object-frameworks-part-3/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 05:49:15 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Mock Object Frameworks]]></category>
		<category><![CDATA[Test Doubles]]></category>
		<category><![CDATA[Unit testing]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/?p=54</guid>
		<description><![CDATA[In part 1 of this series I introduced the idea of substituting collaborating objects with test doubles in order to unit test your classes in isolation. In part 2 I then went on to introduce reasons to choose Rhino Mocks and the four types of test doubles rhino mocks gives you in order to carry [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=54&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://thehumbleprogrammer.wordpress.com/2008/08/01/mock-object-frameworks/">part 1</a> of this series I introduced the idea of substituting collaborating objects with test doubles in order to unit test your classes in isolation. <a href="http://thehumbleprogrammer.wordpress.com/2008/08/17/mock-object-frameworks-part-2/">In part 2</a> I then went on to introduce reasons to choose <a href="http://ayende.com/projects/rhino-mocks.aspx">Rhino Mocks</a> and the four types of test doubles rhino mocks gives you in order to carry out state or interaction based unit testing. In this article I am hoping to introduce testing events as well as some of the more common gotchas that catch out beginner users of Rhino mocks.</p>
<h2>Understanding Error Messages </h2>
<p>For beginner users of the Rhino mocks framework the biggest issue can be in trying to understand the error messages that are returned when an exception is thrown.</p>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Call_GetById_When_Handling_The_View_Load_Event()
{
   <span class="kwrd">this</span>.Setup();
   IService&lt;Customer&gt; serviceMock = repository.StrictMock&lt;IService&lt;Customer&gt;&gt;();
   Expect.Call(serviceMock.GetById(4)).Return(<span class="kwrd">this</span>.customer);
   <span class="kwrd">this</span>.repository.ReplayAll();

   CustomerPresenter presenter = <span class="kwrd">new</span> CustomerPresenter(serviceMock, <span class="kwrd">this</span>.customerViewDMock);
   presenter.HandlePageLoad();
   <span class="kwrd">this</span>.repository.VerifyAll();
}</pre>
</div>
<p>In the test method above I am creating a strict mock on line 3, I then set an expectation that the GetById() will be called and when it is, return the customer instance created earlier in the Setup(). The call to ReplayAll() on the repository lets the framework know that the record phase is complete and we are ready to playback any expectations during the execution of the unit under test. I then create the presenter instance and call the unit under test, which in this case is HandlePageLoad(). Finally I call VerifyAll() on the repository to assert that the expectations set earlier have been met.</p>
<p>When run the test fails with the following message;</p>
<blockquote>
<p><strong>Rhino.Mocks.Exceptions.ExpectationViolationException: IService`1.GetById(4); Expected #1, Actual #0.</strong></p>
</blockquote>
<p>As you can see an ExpectationViolationException has been thrown. The error message that we are interested in begins after the colon, it&#8217;s telling us that a call to IService.GetById(4) was expected once but actually called zero times. In this case I am doing an Interaction based test to ensure that GetById() on the service is called, because I have not implemented the HandlePageLoad() method on the presenter the expectation set in the record phase has not been met during the replay, resulting in the above exception. To fix this I add the following to the HandlePageLoad() method.</p>
<div>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> HandlePageLoad()
{
    Customer toDisplay = <span class="kwrd">this</span>.Service.GetById(4);
}</pre>
</div>
<p>As you can see I have implemented just enough to get the test to pass, I have hard coded in the customer id in the call to <strong>GetById(4).</strong> In reality the customer id will be retrieved from the View.CustomerId property. I change the implementation to make the call to the view like so;</p>
<div>
<pre class="csharpcode">Customer toDisplay = <span class="kwrd">this</span>.Service.GetById(<span class="kwrd">this</span>.View.CustomerId);</pre>
</div>
<p>Now I get the following error message.</p>
<blockquote>
<p><strong>Rhino.Mocks.Exceptions.ExpectationViolationException: IService`1.GetById&lt;System.Int32&gt;(0); Expected #0, Actual #1.<br />IService`1.GetById&lt;System.Int32&gt;(4); Expected #1, Actual #0.</strong></p>
</blockquote>
<p>Because I am using a <a href="http://thehumbleprogrammer.wordpress.com/2008/08/17/mock-object-frameworks-part-2/">strict mock</a> the framework finds two expectation violations. </p>
<ul>
<li>GetById&lt;System.Int32&gt;(0); Expected #0, Actual #1 &#8211; is caused by the call to GetById() in the HandlePageLoad() implementation, because I am now getting the customer id from the view and I have not setup any value for it to return (the view is a strict mock controlled by the framework) customerid will always return the default value, in this case 0. The expectation violation is caused by the GetById(0) being called in the implementation and not having an Expect.Call(&#8230; etc set for it in the record phase of the unit test.
<li>GetById&lt;System.Int32&gt;(4); Expected #1, Actual #0 &#8211; is caused by the Expectation not being met for a call to the GetById(4) method with a parameter value of 4. We explicitly set this expectation in the unit test before the call to ReplayAll().</li>
</ul>
<p>In short this whole issue is being caused by the parameter value being used in setting the expectation, I am using the hard coded value 4 in the expected call to GetById() but in the implementation GetById() is being called with the default customer id, which in this case is 0. We can remedy this situation by using IgnoreArguments like this;</p>
<pre class="csharpcode">Expect.Call(serviceDMock.GetById(4)).<strong>IgnoreArguments().</strong>Return(<span class="kwrd">this</span>.customer);</pre>
<p>Adding a call to IgnoreArguments tells the framework to ignore any values passed into the call to GetById during the execution of the method under test. Now my test is more robust because it will fail when the GetById is not called but if the customer id property changes on the view it will have no effect on the test. </p>
<p>By carefully looking at the error message above we can see that the first part says that a call to IService.GetById(0) was not expected but called anyway and a call to IService.GetById(4) was expected but not met. With value types the clue is in the error message we can see the 0 and the 4 are the parameters making it that bit easier to figure out what is going on. When using reference types we get an even more cryptic error message, by changing the GetById so that it takes a Customer object setting the expectation looks like this; </p>
<div>
<pre class="csharpcode">Expect.Call(serviceMock.GetById(<span class="kwrd">new</span> Customer())).Return(<span class="kwrd">this</span>.customer);</pre>
</div>
<p>and the new implementation looks like this;</p>
<div>
<pre class="csharpcode"><span class="rem">//this is a simple implementation for demo purposes only</span>
Customer toDisplay = <span class="kwrd">this</span>.Service.GetById(<span class="kwrd">new</span> Customer());</pre>
</div>
<p>and when run the error message looks like this;</p>
<blockquote>
<p><strong>Rhino.Mocks.Exceptions.ExpectationViolationException: IService`1.GetById(Rhino.CommonGotchas.Customer); Expected #0, Actual #1.<br />IService`1.GetById(Rhino.CommonGotchas.Customer); Expected #1, Actual #0.</strong></p>
</blockquote>
<p>The parameter being passed in to the GetById(Customer) is the problem. When I set the expectation in the record phase of the unit test I passed in a new Customer and when I implemented the HandlePageLoad() method I also passed&nbsp; in a new Customer in the call to GetById. The framework is using reference equals to check that the parameter being passed in the expectation is the same as the parameter being used in the actual implementation. In this case they are not, so we get the message GetById(Customer) wasn&#8217;t expected but actually called, GetById(Customer) was expected but never called. Again IgnoreArguments sorts this out but the error message is very confusing. </p>
<h3>More Flexibility Using Dynamic Mocks</h3>
<p>I get the two tier error message above because I am using strict mocks and as <a href="http://thehumbleprogrammer.wordpress.com/2008/08/17/mock-object-frameworks-part-2/">we all know from part 2</a> strict mocks will fail a test when either all expected calls have not been met or if unexpected calls are made on the mocked object during the execution of the unit under test. If however we use a dynamic mock in the above example we will only get the one error message. The framework will ignore the fact that a call has been made with the incorrect parameter and will fail on the fact that the expectation has not been met. The expectation has not been met because we have made an explicit expectation that a call to the GetById(param) will be called, we have not let the framework know that the parameters are not important so it will fail the verification. Once I tell the framework to ignore parameters the test will pass. </p>
<p>As a side note this is another reason why I am moving towards using dynamic mocks as apposed to strict mocks. They allow you to write more flexible interaction based tests that will fail for the right reason. So in the example above If someone refactors the implementation in such a way that the call to GetById(int) does not happen then the test will fail, the developer will see a failing test named <strong>Should_Call_GetById_When_Handling_The_View_Load_Event() </strong>and they can then decide whether in light of the refactoring this is a valid test or not.</p>
<h2><strong>Don&#8217;t Forget ReplayAll()</strong></h2>
<p>Not calling replay all on a series of expectations or when setting up results on stubs can cause many side effects, ranging from null pointer exceptions in the best case to an incorrectly passing test in the worst case. The most common time to be caught out by this scenario is when you are stubbing out a collaborator and you just want a quick one line way of setting up a result when the stub is called. The example in this section is for saving a customer that has been updated on the view to the database. The (contrived <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> )&nbsp; implementation&nbsp; of the save method is as follows;</p>
<div>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Save()
{
    Customer customer = <span class="kwrd">this</span>.View.GetCustomer();
    <span class="kwrd">string</span> phoneNumber = customer.Telephone;
    <span class="rem">//do some validation on the phone number....</span>
    <span class="kwrd">this</span>.Service.Save(customer);
}</pre>
</div>
<p>I am getting the updated customer from the view, then getting the telephone number from the returned customer and validating that it meets some criteria finally I am saving it to the database. In my first test for this I want to ensure that only valid phone numbers are being saved to the database, so I stub the view and the service in order to assert state, like so;</p>
<div>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Validate_PhoneNumber_Before_Saving()
{
    <span class="kwrd">this</span>.Setup();
    Service&lt;Customer&gt; serviceStub = repository.Stub&lt;Service&lt;Customer&gt;&gt;();
    ICustomerView viewStub = <span class="kwrd">this</span>.repository.Stub&lt;ICustomerView&gt;(); 

    Customer customerToSave = GetCustomerToSave(); 

    SetupResult.For(viewStub.GetCustomer()).Return(customerToSave);
    serviceStub.Save(<span class="kwrd">new</span> Customer());<span class="rem">//Tell the framework a call to save, which is a void method will be made</span>
    LastCall.Callback(<span class="kwrd">new</span> Delegates.Function&lt;<span class="kwrd">bool</span>, Customer&gt;(<span class="kwrd">this</span>.AssertPhoneNumberIsValid)); <span class="rem">//Set a callback on the call to save so that I can assert on the phone number </span>

    CustomerPresenter presenter = <span class="kwrd">new</span> CustomerPresenter(serviceStub, viewStub);
    presenter.Save();
}</pre>
</div>
</div>
<p>I then setup a result on the GetCustomer() method&nbsp; telling the framework to return the dummy customer when it is called during the execution of the unit under test. On the next line I set a call to a the void method Save(customer) on the service, following it by setting a callback method on the lastcall made by the repository. This callback method will contain all of the assertions on the phone number to ensure that only valid customers are sent to the database. When I run this test I get a null pointer exception in the second line of the Save() method on the presenter. In this line I am trying to retrieve the telephone number from the customer returned from the view, but the view&#8217;s GetCustomer() is returning null. I have set a result on the call to GetCustomer() to return a customer instance so I should not be getting a null pointer. The reason behind this is because I have forgotten to call Repository.ReplayAll() to set the repository into the replay phase. Once I put in the missing line the test works as expected, the test now looks like this;</p>
<div>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Validate_PhoneNumber_Before_Saving()
{
    <span class="kwrd">this</span>.Setup();

    Customer customerToSave = GetCustomerToSave();

    ...
    <span class="kwrd">this</span>.repository.ReplayAll();

    CustomerPresenter presenter = <span class="kwrd">new</span> CustomerPresenter(<span class="kwrd">this</span>.serviceStub, viewStub);
    presenter.Save();
}</pre>
</div>
</div>
<p>As with all of these things I have options, first up I could use a using block with a call to Repository.Record() like this;</p>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Validate_PhoneNumber_Before_Saving()
{
    <span class="kwrd">this</span>.Setup();
    Service&lt;Customer&gt; serviceStub = repository.Stub&lt;Service&lt;Customer&gt;&gt;();
    ICustomerView viewStub = <span class="kwrd">this</span>.repository.Stub&lt;ICustomerView&gt;();

    Customer customerToSave = GetCustomerToSave();

    <span class="kwrd">using</span> (<span class="kwrd">this</span>.repository.Record())
    {
        SetupResult.For(viewStub.GetCustomer()).Return(customerToSave);
        serviceStub.Save(<span class="kwrd">new</span> Customer());<span class="rem">//Tell the framework a call to save, which is a void method will be made</span>
        LastCall.Callback(<span class="kwrd">new</span> Delegates.Function&lt;<span class="kwrd">bool</span>, Customer&gt;(<span class="kwrd">this</span>.AssertPhoneNumberIsValid)); <span class="rem">//Set a callback on the call to save so that I can assert on the phone number</span>
    }

    CustomerPresenter presenter = <span class="kwrd">new</span> CustomerPresenter(serviceStub, viewStub);
    presenter.Save();
}</pre>
</div>
<p>When the record block is exited a call to ReplayAll() is made behind the scenes in that way you don&#8217;t have to remember to call it explicitly. I feel that by using the block in this test increases the noise to code ratio making the code that little bit harder to understand. Also Record blocks are usually followed by PlayBack blocks that make the whole test easier to understand, as a rule of thumb I only use these blocks if I have 3 or more lines of expectations and Stubbed result setup in my tests. I feel that any less than that the using blocks cause too much noise for very little benefit. That is especially so in a state based test where you are purely stubbing out collaborators. </p>
<h2>Setters and Stubs</h2>
<p>Once you get passed the Record/Replay/Verify stuff and you have some understanding of the difference between <a href="http://martinfowler.com/articles/mocksArentStubs.html">Mocks/Stubs/Fakes/Dummies</a> you will probably grow to enjoy using the framework to make your tests easier to write and maintain. As you get more accustomed to using the framework you will probably do as I did and forget that you don&#8217;t have to Setup Results on a stubbed object that has a read/write property, all you need to do is set the property on the stub and it will just work as expected. It seems obvious and it is obvious but you will probably forget about the setter and try to setup result like this;</p>
<p><strong>the view interface</strong></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">interface</span> ICustomerView
{
   <span class="kwrd">int</span> CustomerId { get; }
   Customer Customer { get; set; }
   <span class="kwrd">void</span> AttachDataSource(Customer dataSource);
   Customer GetCustomer();
}</pre>
<p>As you can the Customer property is read/write the test method that stubs out the view is carrying on with the theme outlined above and looks like this;</p>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Validate_PhoneNumber_Before_Saving()
{
   <span class="kwrd">this</span>.Setup();

   Customer customerToSave = GetCustomerToSave();

   <em><strong>SetupResult.For(this.viewStub.Customer).Return(customerToSave);</strong>
</em>   serviceStub.Save(<span class="kwrd">new</span> Customer());<span class="rem">//Tell the framework a call to save, which is a void method will be made</span>
   LastCall.Callback(<span class="kwrd">new</span> Delegates.Function&lt;<span class="kwrd">bool</span>, Customer&gt;(<span class="kwrd">this</span>.AssertPhoneNumberIsValid)); <span class="rem">//Set a callback on the call to save so that I can assert on the phone number</span>
   <span class="kwrd">this</span>.repository.ReplayAll();

   CustomerPresenter presenter = <span class="kwrd">new</span> CustomerPresenter(<span class="kwrd">this</span>.serviceStub, viewStub);
   presenter.Save();
}</pre>
</div>
<p>The third line of the test, in bold, sets up a result on the views&#8217; customer property to return a dummy instance to save. It all looks very familiar, when I run this test I get the following error;</p>
<blockquote>
<p><strong>System.InvalidOperationException: Invalid call, the last call has been used or no call </strong></p>
<p><strong>has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).</strong></p>
</blockquote>
<p>As you can see from the test above I am calling a virtual method and a call has been made, I also don&#8217;t think knowing that the last call has been used really helps me in this scenario. The problem is being caused by me forgetting to set the Customer property directly on the Stubbed view like this;</p>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Validate_PhoneNumber_Before_Saving()
{
   <span class="kwrd">this</span>.Setup();

   Customer customerToSave = GetCustomerToSave();

   <span class="kwrd">this</span>.viewStub.Customer = customerToSave;
   ...
}</pre>
<h2>Testing Events</h2>
<p>There are two areas to testing events, </p>
<ol>
<li>Test that subscribers attach to events correctly</li>
<li>Test that when thrown the event is handled</li>
</ol>
<p>Thankfully rhino mocks gives us some mechanisms to carry out both types of tests. In my first test, again using the theme of a customer presenter instead of using direct calls from the view to the presenter I will be communicating through events. This first test is to ensure that when the presenter is constructed the Load event of the view is attached to. The test looks like this;</p>
<div>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Attach_To_Page_Load_On_View()
{
    <span class="kwrd">this</span>.Setup();

    Expect.Call(() =&gt; <span class="kwrd">this</span>.customerViewDMock.Load += <span class="kwrd">null</span> ).IgnoreArguments();
    <span class="kwrd">this</span>.repository.ReplayAll();

    <span class="kwrd">new</span> CustomerPresenter(<span class="kwrd">this</span>.serviceStub, <span class="kwrd">this</span>.customerViewDMock);
    <span class="kwrd">this</span>.repository.VerifyAll();
}</pre>
</div>
</div>
<p>As you can see it&#8217;s pretty straight forward, in the second line of the test I am setting up an expectation that something will attach to the Load event of the view. I then instruct the framework to IgnoreArguments on the expectation, in this case the null being attached to the Load event. You can also set constraints on the last call specifying things like Is.NotNull on anything attaching to the event. I then instantiate the presenter, which is the unit under test, and verify that all expectations have been met. In order to pass the test I implement the following constructor;</p>
<div>
<pre class="csharpcode"><span class="kwrd">public</span> CustomerPresenter(IService&lt;Customer&gt; service, ICustomerView view)
{
    <span class="kwrd">this</span>.Service = service;
    <span class="kwrd">this</span>.View = view;
    <span class="kwrd">this</span>.View.Load += ((sender, args) =&gt; Console.WriteLine(<span class="str">"view loading"</span>));
}</pre>
</div>
<p>The next thing to test is handling the load event, the first test I want to do is an interaction based test to ensure that the GetById() method is called on the service. My test looks like this;</p>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Call_GetById_On_Service_When_View_Loads()
{
    <span class="kwrd">this</span>.Setup();
    IService&lt;Customer&gt; serviceMock = repository.StrictMock&lt;IService&lt;Customer&gt;&gt;();

    IEventRaiser loadRaiser =
        Expect.Call(() =&gt; <span class="kwrd">this</span>.viewStub.Load += <span class="kwrd">null</span>).IgnoreArguments().<strong>GetEventRaiser();</strong>

    Expect.Call(serviceMock.GetById(4)).Return(<span class="kwrd">new</span> Customer());
    <span class="kwrd">this</span>.repository.ReplayAll();

    <span class="kwrd">new</span> CustomerPresenter(serviceMock, <span class="kwrd">this</span>.viewStub);
    <strong><u>loadRaiser.Raise(<span class="kwrd">this</span>.viewStub, EventArgs.Empty);</u></strong>
    <span class="kwrd">this</span>.repository.VerifyAll();
}</pre>
<p>There are a few subtle differences from the original attach to load event test. I am now using a stub for the view, I set an expectation on the load event in order to get the event raiser, which I have called loadRaiser. This expectation on the stub will never be verified, meaning that the test is more robust to refactoring. I then set the expectation on the service that its&#8217; GetById(4) is called finally setting the repository into replay mode. As in the attach test above, I instantiate the Presenter with the serviceMock and the viewStub. I then use the loadRaiser to Raise the load event, finally verifying that all expectations have been met. The implementation of the constructor now looks like this;</p>
<div>
<pre class="csharpcode"><span class="kwrd">public</span> CustomerPresenter(IService&lt;Customer&gt; service, ICustomerView view)
{
    <span class="kwrd">this</span>.Service = service;
    <span class="kwrd">this</span>.View = view;
    <span class="kwrd">this</span>.View.Load += ((sender, args) =&gt; service.GetById(4));
}</pre>
<h2>Conclusion</h2>
</div>
</div>
<p>As I said from the outset, it is not straight forward, but my hope is that this series will be useful for those of you that wish to go down the route of incorporating dynamic mocking frameworks into your unit tests. This article should help you to avoid some of the pitfalls I went through in trying to understand the feedback from the framework. It should also go some way to convincing you that Rhino mocks gives you a lot of useful features to help you avoid the task of rolling your own fakes. </p>
<p>In the next article I will be writing about some of the new features in Rhino Mocks 3.5 beta and also comparing it with Moq to see which side of the religious argument I fall under.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=54&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2008/09/23/mock-object-frameworks-part-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>
	</item>
		<item>
		<title>Another Stupid User!</title>
		<link>http://thehumbleprogrammer.wordpress.com/2008/09/18/another-stupid-user/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2008/09/18/another-stupid-user/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 06:13:52 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/?p=52</guid>
		<description><![CDATA[A couple of weeks ago my significant other and I decided to buy her father an entry level computer. Having completed a learn direct introductory course at the local&#160; library, and having a considerable amount of free time at the moment we thought the time was right for an early Christmas present. So we opted [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=52&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago my significant other and I decided to buy her father an entry level computer. Having completed a <a href="http://www.learndirect.co.uk/">learn direct</a> introductory course at the local&nbsp; library, and having a considerable amount of free time at the moment we thought the time was right for an early Christmas present. So we opted for a basic <a href="http://www.packardbell.co.uk/">Packard Bell</a> PC from PCWorld. Buying it and setting it up was really simple and within 20 minutes of bringing round to the house John was up and running.</p>
<p>Out came the old learn direct disk, which I have to say I was very impressed with, explaining all of the basic aspects of using the computer. The disk was packed with lots of little games to aid learning too control the mouse and such like. After about an hour of happy learning a dialogue box appeared, which had no cancel facility, luckily my other half was in the room at the time and being the <span style="text-decoration:line-through;">jaded</span> experienced user that she is the dialogue box said;</p>
<blockquote><p><a href="http://blogs.msdn.com/ptorr/archive/2004/01/19/60352.aspx#60731">&#8220;If you want to tech the tech, you need to tech the tech with the teching tech tech. Tech the tech? Yes / No&#8221;</a></p>
</blockquote>
<p>or words to that effect. So John was instructed to click OK and the problem dialogue box would go away. On clicking OK the sound disappeared, at this point first line support for all the families computer needs was summoned to the room. I did the usual checks to see that the sound was not turned down or that it had not been muted. The sound was coming out from the sound card to the speakers in the monitor, so I unplugged the cable and plugged it back in again causing the offending dialogue box to appear again.</p>
<p><a href="http://thehumbleprogrammer.files.wordpress.com/2008/09/packardbell-issue.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" height="397" alt="packardbell_issue" src="http://thehumbleprogrammer.files.wordpress.com/2008/09/packardbell-issue-thumb.jpg?w=484&#038;h=397" width="484" border="0"></a>&nbsp;</p>
<p>As you can see the active window is asking &#8220;Which device did you plug in?&#8221;, so now I am being made to think, and as we all know users <a href="http://www.sensible.com/buythebook.html">shouldn&#8217;t have to think</a>. The device I plugged in was the line out to the monitor. So where is that option then, well ok trial and error time I went through them all and after getting no joy I was convinced that it must be the <strong>Rear speaker out</strong> option and that there must be a problem with the monitor.<strong>&nbsp;</strong>The assumption behind this option being, we had plugged the cable into the rear line out jack (I know, assumption is the mother of all&#8230;.).</p>
<p>After reluctantly admitting defeat I took the machine back to PC world and explained the issue to the tech guys there, within a few minutes the guy came back handed me the base unit saying that it was all sorted. When asked what the fix was, he gave a little chuckle as if to say, don&#8217;t be a dumb user, and then said &#8220;you have to re-task the jacks, and that it was the front speaker out option&#8221;.</p>
<p>All&#8217;s well that ends&#8217; well eh&#8230; Not really, to my mind it should not be that difficult to setup the sound from a computer&#8217;s sound card. The jacks are colour coordinated and so are the connecting cables. I have never had to learn what the colour coding means because on every other system I have setup I just plug the green cable from the speakers into the green jack on the system and hey presto as if by magic, we get sound. Quite simply to put the responsibility of re-tasking a jack into the hands of already overwhelmed novice users&nbsp; is a poor design decision.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/thehumbleprogrammer.wordpress.com/52/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/thehumbleprogrammer.wordpress.com/52/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/52/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=52&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2008/09/18/another-stupid-user/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>

		<media:content url="http://thehumbleprogrammer.files.wordpress.com/2008/09/packardbell-issue-thumb.jpg" medium="image">
			<media:title type="html">packardbell_issue</media:title>
		</media:content>
	</item>
		<item>
		<title>Mock Object Frameworks Part 2</title>
		<link>http://thehumbleprogrammer.wordpress.com/2008/08/17/mock-object-frameworks-part-2/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2008/08/17/mock-object-frameworks-part-2/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 18:26:13 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Mock Object Frameworks]]></category>
		<category><![CDATA[Test Doubles]]></category>
		<category><![CDATA[Unit testing]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/?p=31</guid>
		<description><![CDATA[In the first instalment of this series I introduced the idea behind mocking showing a quick example of hand rolling your own stubs in order to test your classes in isolation. In this article I will be going through the types of test doubles you get from Rhino Mocks and why I chose it in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=31&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://thehumbleprogrammer.wordpress.com/2008/08/01/mock-object-frameworks/">first instalment</a> of this series I introduced the idea behind mocking showing a quick example of hand rolling your own stubs in order to test your classes in isolation. In this article I will be going through the types of test doubles you get from <a href="http://www.ayende.com/projects/rhino-mocks.aspx">Rhino Mocks</a> and why I chose it in the first place.&nbsp; <a href="http://www.ayende.com/wiki/Rhino+Mocks+Documentation.ashx">Rhino Mocks Documentation</a> is a good starting point, after that there are plenty of people blogging on <a href="http://www.google.co.uk/search?hl=en&amp;q=Gettings+Started+with+Rhino+Mocks&amp;meta=">getting started with Rhino Mocks</a>. You can also <a href="http://www.ayende.com/wiki/GetFile.aspx?File=Rhino+Mocks+3.3+Quick+Reference.pdf">download and print a cheat sheet</a>,&nbsp; which is also very useful. For these reasons I won&#8217;t be delving too deeply into the usage of Rhino Mocks, I want to focus more on why you would choose it, what the different types of mock objects are and when to use them.</p>
<h2>Why Choose Rhino Mocks?</h2>
<p>In the previous instalment I outlined several mocking frameworks and some of their main features, at the time of my choosing a framework to use <a href="http://code.google.com/p/moq/">Moq</a> wasn&#8217;t around, had it been I may have chosen that one, I will certainly be looking into some of the claims they make. So with this in mind I ended up going for Rhino Mocks. I discounted <a href="http://sourceforge.net/projects/nmock2/">NMock2</a> and <a href="http://easymock.net/">EasyMock</a> because they use strings for setting expectations e.g.</p>
<div>
<pre class="csharpcode">Expect.Call("mockObject.SomeMethodOrProperty")
</pre>
</div>
<p>The problem with this approach is that if you change the name of any of the methods or properties being mocked the change will not be propagated to your tests. Refactoring is something I do all the time, as my understanding of the system improves I will refactor the code to express this new understanding. Visual Studio is improving in this area by giving us some basic refactoring support. The idea that I would have to do a search and replace in my test suite was a non starter in my mind.</p>
<p>In the end it was between Rhino Mocks and TypeMock. I discounted TypeMock because it&#8217;s too powerful. This may seem like a strange reason but I would urge all novice mockers to avoid TypeMock like the plague (links to typemock omitted deliberately <img src='http://s1.wp.com/wp-includes/images/smilies/icon_surprised.gif' alt=':-o' class='wp-smiley' /> ). The fact that you can mock anything is the problem, I believe in unit testing as a way of minimising bugs in your system, leading me to want to build testable systems. A deeply embedded dependency, such as a static call to a method that hits the database means that it cannot be tested in isolation without the use of TypeMock. So what, I hear you say, the system can still be tested and the method can be tested in isolation, so there is no problem right? Well if you have considered the effects of this embedded dependency and have decided that they are within acceptable boundaries then by all means carry on. You have done some thinking and recognised the tradeoffs and made an informed decision, that is what software development is all about, too avoid being a <a href="http://en.wikipedia.org/wiki/Cargo_cult_programming">Cargo Cult Programmer</a>. If on the other hand you embed that dependency because that is all you know, and with the help of TypeMock you can keep the coverage high as your system evolves into a nice <a href="http://www.laputan.org/mud/">big ball of mud</a>, then you have problems, more specifically the maintainer of your code will have problems, lets hope they are not a <a href="http://www.codinghorror.com/blog/archives/001137.html">psychopathic axe murder</a>, or worse yourself.</p>
<h2>Different types of test doubles</h2>
<p>Out of the box Rhino gives us four different types of test doubles, each one is specific to different scenarios. The four are</p>
<h3><a href="http://www.ayende.com/Wiki/(S(wq3mncrnihpe21e2gtyuidj3))/Rhino+Mocks+-+Stubs.ashx">Stub</a></h3>
<p>Gives us a ready to use sub classed implementation of the collaborating class we want to substitute in our tests. A stub offers us a mechanism to inject test data into our unit under test without having the method call to the stub verified.&nbsp; If you are doing a classic state based test where the unit under test collaborates with some object that you want to substitute then use a stub. Here is an example method that I want to test</p>
<div>
<pre class="csharpcode">public string FormatContactDetails(Message message)
{
    <span style="color:#0000ff;">string</span> contactDetails = message.GetContactDetails();
    <span style="color:#008000;">//formating code here...</span>
    <span style="color:#0000ff;">return</span> contactDetails;
}</pre>
</div>
<p>This method could be from some messaging system where I want to get contact details from the given message, I don&#8217;t have any control over how the message is created I just know that it is part of the messaging framework. I want to do a state based test that the returned string is in the correct format, but I don&#8217;t want to go to the hassle of creating a Message instance because it may have too many dependencies on the framework. The test would look something like this</p>
<div>
<div>
<pre class="csharpcode">[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> Should_Return_ContactDetails_In_Correct_Format()
{
    MockRepository mockRepository = <span class="kwrd">new</span> MockRepository();
    <span class="rem">//you could also use MockRepository.GenerateStub&lt;Message&gt;();</span>
    Message messageStub = mockRepository.Stub&lt;Message&gt;();

    SetupResult.For(messageStub.GetContactDetails()).Return(<span class="str">"some contact details"</span>);
    mockRepository.ReplayAll();

    Customer customer = <span class="kwrd">new</span> Customer();
    <span class="kwrd">string</span> formattedDetails = customer.FormatContactDetails(messageStub);

    <span class="rem">//Make assertions on the state of formattedDetails</span>
}</pre>
</div>
</div>
<p>I create a stubbed message by calling Stub&lt;Message&gt;() on the repository of mocked objects. I then setup the test data to be used in the unit under test by calling <strong>SetupResult.For</strong>, this line tells the framework to return the string &#8220;some contact details&#8221; when <strong>GetContactDetails()</strong> is called during the execution of <strong>customer.FormatContactDetails</strong>, which is the unit under test. Calling <strong>mockRepository.ReplayAll()</strong> will move all of the mocked/stubbed objects in the repository from the record state into the replay state. Finally I can make all the assertions I need on the returned string to ensure that the formatted details are correct.</p>
<p><a href="http://www.ayende.com/Wiki/(S(wq3mncrnihpe21e2gtyuidj3))/Rhino+Mocks+-+Stubs.ashx"></a></p>
<h3><a href="http://www.ayende.com/Wiki/(S(wq3mncrnihpe21e2gtyuidj3))/Rhino+Mocks+-+Stubs.ashx">Dynamic Mock</a></h3>
<p>Dynamic mocks give you loose replay semantics, this means that all expectations that are set must be met or your test will fail, but unexpected method calls will not cause the test to fail. You can use dynamic mocks as stubs but as the <a href="http://www.ayende.com/Wiki/(S(wq3mncrnihpe21e2gtyuidj3))/Rhino+Mocks+-+Stubs.ashx">stub documentation</a> suggests this is a lot of work for very little gain. Dynamic mocks come in handy on the rare occasion when you may have one method call to a collaborator that you care about whilst all other interactions with the same collaborator are not so essential.</p>
<p><strong>UPDATE: 11.10.2008</strong> &#8211; With the release of Rhino Mocks 3.5, <a href="http://ayende.com/Wiki/Rhino+Mocks+3.5.ashx">Ayende confirmed</a> what I had already concluded myself;</p>
<blockquote>
<p>CreateMock is deprecated, replaced by StrictMock. The use of Strict Mock is discouraged</p>
</blockquote>
<p>We should be using dynamic mocks instead of strict mocks, making our tests less brittle and easier to refactor.</p>
<h3><a href="http://www.ayende.com/Wiki/(S(wq3mncrnihpe21e2gtyuidj3))/Rhino+Mocks+Partial+Mocks.ashx">Partial Mock</a></h3>
<p>As the documentation suggests (the heading is a link <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ) partial mocks are useful for when you want to test abstract methods in isolation. Another use for partial mocks is when breaking dependencies in a <a href="http://timross.wordpress.com/2008/06/18/legacy-code-can-be-fun/">legacy code base</a>. By legacy code I mean untested tightly coupled spaghetti code that most of us see produced by the A grade whiz bang team assembled to get version 1 of the latest Greenfield project going, and this time they are going to get it right <img src='http://s1.wp.com/wp-includes/images/smilies/icon_surprised.gif' alt=':-o' class='wp-smiley' /> . Anyway an example of said code could be.</p>
<div>
<pre class="csharpcode">public string FormatContactDetails()
{
    <span style="color:#0000ff;">string</span> formattedDetails = string.Empty;
    ContactDetails details = ServiceController.Instance.GetContactDetails(this.CustomerID);
    //code to turn the contactDetails into a formatted string

    <span style="color:#0000ff;">return</span> formattedDetails;
}</pre>
</div>
<p>In order to test the FormatContactDetails method in isolation I want to break the dependency on that static call to the database using the <strong>ServiceController. </strong>The point of my test at this stage is to ensure that the returned string is in the correct format, I don&#8217;t care about the database call, that should have been tested in an integration test suite. The first thing to do is to move it out into a public virtual method</p>
<div>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">string</span> FormatContactDetails()
{
    <span class="kwrd">string</span> formattedDetails = <span class="kwrd">string</span>.Empty;
    ContactDetails details = GetContactDetails();
    <span class="rem">//code to turn the contactDetails into a formatted string</span>

    <span class="kwrd">return</span> formattedDetails;
}

<span class="kwrd">public</span> <span class="kwrd">virtual</span> ContactDetails GetContactDetails()
{
    <span class="kwrd">return</span> ServiceController.Instance.GetContactDetails(this.CustomerID);
}</pre>
</div>
<p>then I can sub class and override it in my tests. I can use a partial mock for this,</p>
<div>
<pre class="charpcode">[Test]
public void Should_Get_formatted_ContactDetails_Without_Hitting_The_DB()
{
Customer customer = this.mockRepository.PartialMock&lt;Customer&gt;();

Expect.Call(customer.GetContactDetails()).Return("just testing");
this.mockRepository.ReplayAll();

string formattedAddress = customer.FormatContactDetails();

Assert.AreEqual("just testing", formattedAddress);
}
</pre>
</div>
<p>I have created a partial mock of the Customer class where the FormatContactDetails behaviour resides, I am then setting up an expected call on the virtual method <strong>GetContactDetails </strong>telling the framework that when the method call is executed return &#8220;just testing&#8221;. After moving the partial mock to the replay state from the record state I then call the unit under test. Finally I can make some assertions on the returned string to see that it is in the correct format, although I haven&#8217;t done in this test you can also verify that the expected call has been met.</p>
<p><a href="http://www.ayende.com/wiki/Rhino+Mocks+-+Another+Introduction.ashx"></a></p>
<h3><a href="http://www.ayende.com/wiki/Rhino+Mocks+-+Another+Introduction.ashx">Mock</a></h3>
<p>Mock implementations of collaborating classes enable us to verify that methods were called correctly during the execution of the unit under test. Mocks are used when the interaction between a unit under test and it&#8217;s collaborators is the essence of the test. Mocking a collaborator gives us a strict record/replay model, this means that every expectation that is set must be met, also If a method is called on a mocked object without setting an expectation the test will fail.&nbsp; When you mock an object using a call to <strong>CreateMock </strong>like so</p>
<div>
<pre class="csharpcode">Customer customer = <span class="kwrd">this</span>.mockRepository.CreateMock&lt;Customer&gt;();</pre>
</div>
<p>you are saying that this is an interaction based test, the interaction between the unit under test and the mocked object is all important. It should be verified that all expectations have been met and that no calls have been made on the mocked object unexpectedly.</p>
<h2>Conclusion</h2>
<p>In this article I explained the reasons behind my choosing Rhino mocks for dynamically mocking dependent objects in my unit tests. I also went through the four types of test doubles that Rhino mocks gives you out of the box. These four types should give you all the functionality you need to unit test your classes in isolation without having too maintain a suite of hand rolled fakes, as you refactor your system. The important thing to realise is that there is more to a dynamic mock object framework than just pure mocking to enable interaction based testing. With this in mind you should have a clear understanding of what is important in each unit test and use the framework accordingly.</p>
<p>In the next instalment I will be outlining some general rules of thumb for incorporating Rhino mocks in your tests, I will also delve into some of the more common gotchas that may have you scratching your head when you first start using the framework.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/thehumbleprogrammer.wordpress.com/31/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/thehumbleprogrammer.wordpress.com/31/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/31/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=31&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2008/08/17/mock-object-frameworks-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>
	</item>
		<item>
		<title>Mock Object Frameworks</title>
		<link>http://thehumbleprogrammer.wordpress.com/2008/08/01/mock-object-frameworks/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2008/08/01/mock-object-frameworks/#comments</comments>
		<pubDate>Fri, 01 Aug 2008 21:20:29 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Unit testing]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/2008/08/01/mock-object-frameworks/</guid>
		<description><![CDATA[In the last 18 months I have been doing a good deal of experimentation with mock object frameworks. Trying to understand mocking frameworks, when to use them and when not to has been a painful experience, but one that I feel everyone should go through in order to come out the other side, with a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=16&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In the last 18 months I have been doing a good deal of experimentation with mock object frameworks. Trying to understand mocking frameworks, when to use them and when not to has been a painful experience, but one that I feel everyone should go through in order to come out the other side, with a deep seated knowledge of building testable systems. This is the first in a series of posts explaining my understanding of mock objects and the frameworks out there.</p>
<h2>Introduction</h2>
<p>Substituting real implementations of an interface with a mocked implementation is a technique used in unit testing that gives you the following benefits:</p>
<ol>
<li>Keeps your unit tests fast running.
<li>Enables you to test your classes in isolation.
<li>Usually leads to a well designed loosely coupled system. </li>
</ol>
<p>Fast running unit tests are essential to keeping the developers interested in running and maintaining test coverage during the development of a system. When I first tried unit testing a production system I soon became unstuck with tests that relied upon external resources that I had no control over such as database calls, SMTP, the file system etc. When this happens the tests become unrepeatable and slow, from then on other developers didn&#8217;t run the tests often, meaning that the test suite became an un trusted, maintenance nightmare with very little benefit. In order to keep your tests running fast you must mock out these external dependencies, tests that incorporate the database calls etc can, and should be included in an integration test suite that is separate from your unit tests. Points two and three are resulting side effects that are beneficial in their own right when you have a fast running, repeatable suite of unit tests.</p>
<p>The mistakes I made in the above mentioned project lead me down the path of Mock object frameworks. So far in this article I have used the term Mock to mean any type of implementation used as a substitute in your tests. There are several different types of <a href="http://xunitpatterns.com/index.html">Test Doubles</a> that can be used, each of them enable you to take different approaches in your unit tests. Over this series of articles I will be delving more deeply into the different approaches to writing unit tests but for now I will use <a href="http://martinfowler.com/">Martin Fowler&#8217;s</a> definitions from his article <a href="http://martinfowler.com/articles/mocksArentStubs.html">Mocks Aren&#8217;t Stubs</a> without going into too much detail.</p>
<blockquote><p><strong>Mock objects</strong></p>
<p>pre-programmed with expectations which form a specification of the calls they are expected to receive</p>
</blockquote>
<blockquote><p><strong>Stubs</strong></p>
<p>provide canned answers to calls made during the test, usually not responding at all to anything outside what&#8217;s programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it &#8216;sent&#8217;, or maybe only how many messages it &#8216;sent&#8217;.</p>
</blockquote>
<blockquote><p><strong>Fakes</strong></p>
<p>objects actually have working implementations, but usually take some shortcut which makes them not suitable for production</p>
</blockquote>
<p>A common example throughout these articles will be to develop a Presenter that collaborates with a view and a model <a href="http://en.wikipedia.org/wiki/Model_View_Presenter">(MVP)</a>, I will be substituting implementations of these dependent objects with mocks/stubs/fakes. This allows me to construct the presenter without worrying about the implementation details of the view and the model. In my opinion this is a very important benefit of mocking because it allows me to concentrate on doing one thing and one thing only.</p>
<h2>The Manual Approach</h2>
<p>The manual approach to achieving this isolation is to implement your own stubs that return test data when the methods are called. The following is a CustomerOrdersPresenter that interacts with an ICustomerOrdersView and an IDataProvider (the model). In the constructor of the presenter I want to attach to the views load event so my test for this is&#8230;</p>
<p><code>[Test]<br />public void Should_Attach_To_Load_Event()<br />{<br />ICustomerOrdersView customerOrdersViewStub = new CustomerOrdersViewStub();<br />CustomerOrdersPresenter presenter =<br />new CustomerOrdersPresenter(customerOrdersViewStub, _customersDataProvider);<br />Assert.IsNotNull(presenter, "Presenter should not be null");<br />Assert.IsTrue(((CustomerOrdersViewStub)customerOrdersViewStub).InvocationListCount &gt; 0,<br />"the invocation list of the Load event should be greater than 0");<br />}</code></p>
<div>As you can see I have created a new instance of the CustomerOrdersViewStub, which is my own hand rolled implementation of the ICustomerOrdersView. As well as implementing the interface functionality I have added some properties and methods to allow me to write useful tests. In this case I have added a InvocationListCount property that allows me to get at the Load events invocation list.</div>
<p><code>internal class CustomerOrdersViewStub : ICustomerOrdersView<br />{<br />//ICustomersView implementation<br />....<br />//added property for testing<br />public int InvocationListCount<br />{<br />get { return this.Load.GetInvocationList().Length; }<br />}<br />}</code></p>
<p>Finally the implementation of the CustomerOrdersPresenter&#8217;s constructor is</p>
<p><code>public class CustomerOrdersPresenter<br />{<br />private readonly ICustomerOrdersView _view;<br />private readonly IDataProvider _provider;<br />public CustomerOrdersPresenter(ICustomerOrdersView view) :this(view, new CustomerDataProvider())<br />{ }<br />public CustomerOrdersPresenter(ICustomerOrdersView view, IDataProvider provider)<br />{<br />_view = view;<br />_provider = provider;<br />_view.Load += new EventHandler(View_Load);<br />}<br />}<br /></code></p>
<div>The benefits of the manual method are</div>
<ul>
<li>No learning curve (we all know how to write code).
<li>Complete control over the stub </li>
</ul>
<div>The downside of the manual method is</div>
<ul>
<li>Can quickly become a nightmare to maintain two sets of implementations.
<li>A lot of code to write just to get useful fine grained tests. </li>
</ul>
<p>Although the downside to the manual method is quite significant I would advise anyone starting out unit testing to use it until they are completely happy with writing good unit tests. With hindsight I probably went over to mock object frameworks too early in my unit testing career, this lead to a lot of frustration with trying to learn two things at once.</p>
<h2>Mocking Frameworks</h2>
<p>In order to avoid writing your own stubs for testing purposes you can incorporate a mock object framework to do the work for you. As I said earlier I found the learning curve is pretty steep but as with all things it gets easier over time. Of course some of you geniuses out there will probably get it straight away, or you may have a colleague who has used the frameworks before. All I can say is give yourself a pat on the back and sit back with your hands cradling the back of your head allowing a nice smug grin to appear on your face.For the rest of us the different frameworks are:</p>
<ul>
<li><a href="http://www.typemock.com/"><strong>TypeMock</strong></a>
<ul>
<li>Free and professional versions.
<li>Allows you to mock anything, including static methods.
<li>Has a fluent interface.
<li>pro version is quite expensive.
<li>You don&#8217;t have to inject mocked objects </li>
</ul>
<li><a href="http://sourceforge.net/projects/nmock2/"><strong>NMock2</strong></a>
<ul>
<li>Free open source project.<strong> </strong>
<li>Allows you to mock classes and interfaces.
<li>Uses strings to set the expectations on method calls.
<li>Uses a fluent interface.
<li>You have to <a href="http://en.wikipedia.org/wiki/Dependency_injection">inject dependent</a> mock implementations in order to set expectations on them. </li>
</ul>
<li><a href="http://www.ayende.com/projects/rhino-mocks.aspx"><strong>RhinoMocks</strong></a>
<ul>
<li>Free open source project.
<li>Allows you to mock classes, interfaces and delegates.
<li>Developed with refactoring in mind, by using the strongly typed mock object&#8217;s instead of strings to set your expectations.
<li>Uses a fluent interface.
<li>You have to use <a href="http://martinfowler.com/articles/injection.html">Dependency Injection</a> in order to substitute the real implementation with a mock/stub. </li>
</ul>
<li><a href="http://code.google.com/p/moq/"><strong>MoQ</strong></a>
<ul>
<li>Free open source project.
<li>Allows you to mock classes, interfaces and delegates.
<li>Uses strongly typed mocks when setting expectations.
<li>Uses a fluent interface.
<li>No record/replay/verify syntax </li>
</ul>
</li>
</ul>
<p>With the exception of MoQ all of the frameworks use a record/replay/verify model. This means that you record a set of expected behaviour then you verify that all of the expectations were met after the replay. The record/replay model is only important when you are using pure mock objects (not stubs) in an <a href="http://benpryor.com/blog/2007/01/16/state-based-vs-interaction-based-unit-testing/">interaction based test</a>. State based testing is the more familiar to most developers, where you set up some test data and call the unit under test and assert that the state of the object meets some post condition. When doing interaction based testing the assertions being made are based on the interaction between the unit under test and its&#8217; collaborators. This will hopefully become clearer as I produce some demo code in later instalments of this series.</p>
<p>In the next article I will be delving into the reasons behind why I chose RhinoMocks. I will also be showing more code examples of writing unit tests using RhinoMocks.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/thehumbleprogrammer.wordpress.com/16/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/thehumbleprogrammer.wordpress.com/16/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/16/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=16&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2008/08/01/mock-object-frameworks/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>
	</item>
		<item>
		<title>Not another one!</title>
		<link>http://thehumbleprogrammer.wordpress.com/2008/07/03/about-m/</link>
		<comments>http://thehumbleprogrammer.wordpress.com/2008/07/03/about-m/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 06:07:35 +0000</pubDate>
		<dc:creator>thehumbleprogrammer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://thehumbleprogrammer.wordpress.com/2008/07/03/about-m/</guid>
		<description><![CDATA[Hi, my name is Dermot Kilroy. I am a .NET developer living in London, currently working in the Media industry on the content management system for one of Britain&#8217;s largest websites. My interest in computers began way way back in the days of windows 95/98. I had reached the dizzying heights of middle management in the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=1&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Edsger_W._Dijkstra"></a>Hi, my name is Dermot Kilroy. I am a .NET developer living in London, currently working in the Media industry on the content management system for one of Britain&#8217;s largest websites.</p>
<p>My interest in computers began way way back in the days of windows 95/98. I had reached the dizzying heights of middle management in the service industry and now had to use a PC as part of my job. As a typical user I found them to be incredibly frustrating and always wanted to do things in a different way to that suggested by the help files. The frustration of not understanding what was going on under the hood led me on a quest through formal education in Internet computing at <a href="http://www.lsbu.ac.uk/">The London South Bank</a> university. I graduated from University in 2005 and have been working on Asp.Net C# applications ever since.</p>
<p>I have started this blog for one simple reason: have you seen what&#8217;s happened to <a href="http://www.codinghorror.com/blog">Jeff Attwood </a>since he started waffling on in 2004? I figure i can waffle with the best of them, so watch out blogosphere I&#8217;m coming to get ya. Oh yeah and I also have a lot to learn and say on all the usual topics of agile software development. Also it makes a nice way for me to formalise my learning with a searchable repository of topics related to software development, as well as a place for me to vent about the software industry in general from time to time. Finally, if only one person learns something from my ramblings on these pages then I will be happy that my work was not in vain. Hi mum I am on the Interweb&#8230;</p>
<p>I have chosen the humble programmer as the title of my blog <a href="http://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340.html">after the paper</a> by <a href="http://en.wikipedia.org/wiki/Edsger_W._Dijkstra">Edsger W. Dijkstra</a>. The essence of the paper struck a chord with my approach to software development:</p>
<blockquote><p>The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.</p></blockquote>
<p>Throughout university and in my short career thus far I have felt that our industry promotes the need to hide the fact that sometimes we just don&#8217;t get it. This attitude stops us asking the simple questions that need to be asked for fear of being labeled as stupid. After reading Dijkstra&#8217;s paper I realised that I had to be confident in what I do know and willing to work really hard to learn and understand what I don&#8217;t. I figure that by publishing what I do know that I might be able to help someone by passing on that knowledge. I also want to learn from the collective power of the web and I am sure that if my understanding of a topic is less than correct, people will let me know.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/thehumbleprogrammer.wordpress.com/1/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/thehumbleprogrammer.wordpress.com/1/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thehumbleprogrammer.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thehumbleprogrammer.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thehumbleprogrammer.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thehumbleprogrammer.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thehumbleprogrammer.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thehumbleprogrammer.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thehumbleprogrammer.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thehumbleprogrammer.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thehumbleprogrammer.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thehumbleprogrammer.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thehumbleprogrammer.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thehumbleprogrammer.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thehumbleprogrammer.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thehumbleprogrammer.wordpress.com/1/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thehumbleprogrammer.wordpress.com&amp;blog=4130395&amp;post=1&amp;subd=thehumbleprogrammer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thehumbleprogrammer.wordpress.com/2008/07/03/about-m/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e8d6815dd1d6e272f2ea799e3fd6d8f7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thehumbleprogrammer</media:title>
		</media:content>
	</item>
	</channel>
</rss>
