<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;Ak4MQ384eip7ImA9WxNUF0Q.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662</id><updated>2009-11-09T20:36:22.132Z</updated><title>Robust Software</title><subtitle type="html">Tales of a code samurai</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.robustsoftware.co.uk/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/RobustSoftware" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;Ak4MQ38_eSp7ImA9WxNUF0Q.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-1200464228302377202</id><published>2009-11-09T20:36:00.001Z</published><updated>2009-11-09T20:36:22.141Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-09T20:36:22.141Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDD" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="BDD from scratch" /><title>What is BDD (Behaviour Driven Design)?</title><content type="html">&lt;p&gt;“What is BDD?” is a question that’s been doing the rounds lately within the &lt;a href="http://www.altnetgroup.com" target="_blank"&gt;altnetgroup&lt;/a&gt; and &lt;a href="http://search.twitter.com/search?q=%23devbookclub" target="_blank"&gt;devbookclub&lt;/a&gt;. There’s a great deal of mysticism surrounding it as if it were some exclusive members club. I’m going to slay some of the myths and tell you what BDD really is.&lt;/p&gt;  &lt;h3&gt;Myth 1: BDD requires a framework or tool&lt;/h3&gt;  &lt;p&gt;You don’t need to use &lt;a href="http://github.com/machine/machine.specifications" target="_blank"&gt;MSpec&lt;/a&gt;, &lt;a href="http://rspec.info/" target="_blank"&gt;RSpec&lt;/a&gt;, &lt;a href="http://cukes.info/" target="_blank"&gt;Cucumber&lt;/a&gt;, etc to practice BDD. Sure they can help but they are not a precursor to being a practitioner of BDD. You don’t even have to write your tests within a certain construct such as Given-When-Then.&lt;/p&gt;  &lt;h3&gt;Myth 2: BDD requires UAT&lt;/h3&gt;  &lt;p&gt;User Acceptance Testing is a great concept but is one of those practices that only the elite working with an exceptional client get to do in real life. If you have UAT as part of your process, all power to you, but that’s all it is, part of your process. It is not part of BDD. It is merely coincidental that BDD style tests are the best way to express your acceptance tests.&lt;/p&gt;  &lt;h3&gt;Myth 3: BDD has to be done top-down&lt;/h3&gt;  &lt;p&gt;It is easier to approach BDD in a top down manner. But much like its easier to put your underwear on first, that doesn’t work for everyone in every situation. Just ask Superman. The proponents of BDD often state things in a radical fashion due to a fear of BDD being thrown in the same pot as TDD. That doesn’t mean that every time they say “you must” they actually mean it.&lt;/p&gt;  &lt;h3&gt;So what is BDD?&lt;/h3&gt;  &lt;p&gt;At its core, BDD is TDD done with a specific mindset; testing the intent of the system rather than testing a particular piece of code. The difference is subtle but the effects are large. There’s &lt;a href="http://en.wikipedia.org/wiki/Neuro-linguistic_programming" target="_blank"&gt;an entire discipline dedicated to the power of semantics&lt;/a&gt; after all.&lt;/p&gt;  &lt;p&gt;It is the difference between “when I add a new post to my blog, the new post shows up on my homepage” and “calling the create new post method on the blog controller saves a new post and the new post is passed to the homepage view when the home controller’s index action is called”. Both sentences describe the same code, the BDD style signals the intent and is decoupled from the implementation. The non-BDD style describes what the code is doing almost line for line. The decoupling of the tests from the implementation is where the largest benefit of BDD comes from. Your tests will be less brittle making refactoring easier, perhaps even fun, making your code more malleable.&lt;/p&gt;  &lt;p&gt;The myths aren’t completely unfounded, using constructs such as Given-When-Then helps enforce the required mindset. Frameworks such as MSpec, RSpec, Cucumber or even &lt;a href="http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html" target="_blank"&gt;a bespoke one&lt;/a&gt; help you write tests within that construct. Working from the top-down helps you work from the behaviour of the user interface down to the behaviour of the data access. UAT helps you drive the behaviour of the system from the requirements of the client.&lt;/p&gt;  &lt;p&gt;That’s all these things do though, help you develop in the BDD style. You can still write your code in a non-BDD style using all these frameworks, tools and processes, just as you can develop in the BDD style using none of them.&lt;/p&gt;  &lt;h4&gt;BDD is a state of mind.&lt;/h4&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-1200464228302377202?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bjoKk42XVyA:xPJU4v7RYMU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bjoKk42XVyA:xPJU4v7RYMU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/bjoKk42XVyA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1200464228302377202?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1200464228302377202?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/bjoKk42XVyA/what-is-bdd-behaviour-driven-design.html" title="What is BDD (Behaviour Driven Design)?" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/11/what-is-bdd-behaviour-driven-design.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEMRHczeSp7ImA9WxNRGEs.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3844629243516606702</id><published>2009-09-13T17:51:00.001+01:00</published><updated>2009-09-13T17:51:25.981+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-13T17:51:25.981+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="BDD from scratch" /><category scheme="http://www.blogger.com/atom/ns#" term="Quality" /><title>BDD from scratch – Build your own framework (Part 2)</title><content type="html">&lt;p&gt;In part one I covered how to &lt;a href="http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html" target="_blank"&gt;organise your tests into the Given-When-Then style&lt;/a&gt; through the use of an abstract base class. In this post I’m going to show how you can manage your mocks more efficiently. Though not really a part of &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; I’ve found it very useful in clarifying the behaviour described in my tests as it reduces the amount of noise caused by the definition of variables.&lt;/p&gt;  &lt;p&gt;I’m going to walk you through an example test, starting off with what we finished off with in part 1. We are going to be testing this standard ASP.NET MVC controller method:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Controllers&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;Controller&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt; bookService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt; authenticationService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; BooksController(&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt; bookService, &lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt; authenticationService)&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;this&lt;/span&gt;.bookService = bookService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;this&lt;/span&gt;.authenticationService = authenticationService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; YourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; currentUser = authenticationService.CurrentUser();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ViewData.Model = bookService.OwnedBy(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;return&lt;/span&gt; View(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I’m going to be using &lt;a href="http://code.google.com/p/moq/" target="_blank"&gt;Moq&lt;/a&gt; as my mocking framework for this test; again I’ve applied the same concept to other frameworks such as &lt;a href="http://ayende.com/projects/rhino-mocks.aspx" target="_blank"&gt;Rhino Mocks&lt;/a&gt;. Here is how our test starts out:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Test.Controllers.Books&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;DisplayingYourBooks&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt; factory;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; controller;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt; bookService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt; authenticationService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; result;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt; yourBooks;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt; currentUser;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; factory = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt;(&lt;span style="font-weight: bold; color: #6897bb"&gt;MockBehavior&lt;/span&gt;.Loose);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bookService = factory.Create&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; authenticationService = factory.Create&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; yourBooks = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; currentUser = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; authenticationService.Setup(x =&amp;gt; x.CurrentUser()).Returns(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bookService.Setup(x =&amp;gt; x.OwnedBy(currentUser)).Returns(yourBooks);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; controller = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt;(bookService.Object, authenticationService.Object);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = controller.YourBooks();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ShownYourBooksView()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;, result.ViewName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; PassedListOfYourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreSame(yourBooks, result.ViewData.Model);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The obvious step to reduce the amount of test code on display would be to move the setup of the MockFactory up into the base class. We’re going to take it a step further than that though and introduce a mock management class. Here is what it looks like:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockManager&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt; factory;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #6897bb"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;object&lt;/span&gt;&amp;gt; mockDictionary;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; MockManager()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; factory = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt;(&lt;span style="font-weight: bold; color: #6897bb"&gt;MockBehavior&lt;/span&gt;.Loose);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mockDictionary = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;object&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;T&amp;gt; Mock&amp;lt;T&amp;gt;() &lt;span style="font-weight: bold; color: #cc7832"&gt;where&lt;/span&gt; T : &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; type = &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(T);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;if&lt;/span&gt; (!mockDictionary.ContainsKey(type))&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mockDictionary.Add(type, factory.Create&amp;lt;T&amp;gt;());&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;return&lt;/span&gt; mockDictionary[type] &lt;span style="font-weight: bold; color: #cc7832"&gt;as&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;T&amp;gt;;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is a wrapper around a dictionary of mock objects. When we ask for a mock that has not been requested before, one is created. Otherwise, the previously created mock is retrieved from the dictionary and returned. We’ll add the creation of the mock manager to our abstract base class and expose the Mock&amp;lt;T&amp;gt; method for use within our tests:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockManager&lt;/span&gt; mockManager;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;T&amp;gt; Mock&amp;lt;T&amp;gt;() &lt;span style="font-weight: bold; color: #cc7832"&gt;where&lt;/span&gt; T : &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;return&lt;/span&gt; mockManager.Mock&amp;lt;T&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixtureSetUp&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Setup()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mockManager = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockManager&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Now we can utilise the mock manager within our original test, reducing the lines of code considerably:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Test.Controllers.Books&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;DisplayingYourBooks&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; controller;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; result;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt; yourBooks;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt; currentUser;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; yourBooks = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; currentUser = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.CurrentUser()).Returns(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.OwnedBy(currentUser)).Returns(yourBooks);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; controller = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt;(Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Object, Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Object);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = controller.YourBooks();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ShownYourBooksView()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;, result.ViewName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; PassedListOfYourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreSame(yourBooks, result.ViewData.Model);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;As we no longer have to worry about variable declaration and assignment for our mocks, we can leave the test code to signal the intent of our test. As there is no real setup for the fields currentUser and yourBooks, I’d be tempted to in-line those variables but this is a matter of personal taste:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Test.Controllers.Books&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;DisplayingYourBooks&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; controller;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; result;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt; yourBooks = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt; currentUser = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.CurrentUser()).Returns(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.OwnedBy(currentUser)).Returns(yourBooks);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; controller = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt;(Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Object, Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Object);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = controller.YourBooks();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ShownYourBooksView()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;, result.ViewName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; PassedListOfYourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreSame(yourBooks, result.ViewData.Model);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;As you can see, this reduces the amount of code required to establish the same context to test a given behaviour. The less lines of code you need to set up a test, the easier it is going to be to understand that test in the future. This, along with the more explanatory naming of your test, makes it much easier to maintain that test in the future.&lt;/p&gt;  &lt;p&gt;Next up, I’ll show how we can utilise our MockManager to implement auto mocking. This will reduce the amount of code in our test slightly, but more importantly it makes our test suite less brittle.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Related posts&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html" target="_blank"&gt;BDD from scratch - Part 1&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/05/difference-between-areequal-and-aresame.html" target="_blank"&gt;Difference between AreEqual and AreSame&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html" target="_blank"&gt;Test aided development&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3844629243516606702?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=o3HfdRYSpHI:Hy0R_pD3vpA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=o3HfdRYSpHI:Hy0R_pD3vpA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/o3HfdRYSpHI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3844629243516606702?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3844629243516606702?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/o3HfdRYSpHI/bdd-from-scratch-build-your-own_13.html" title="BDD from scratch – Build your own framework (Part 2)" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own_13.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcGSXg6cCp7ImA9WxNREkg.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-9068096885841795344</id><published>2009-09-06T16:00:00.000+01:00</published><updated>2009-09-06T17:20:28.618+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-06T17:20:28.618+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="BDD from scratch" /><category scheme="http://www.blogger.com/atom/ns#" term="Quality" /><title>BDD from scratch – Build your own framework (Part 1)</title><content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; is a higher level of unit testing, it creates better documentation of your system by recording its intent which makes your system easier to learn for new developers and relearn for when you revisit your code further down the line.&lt;/p&gt;  &lt;p&gt;I’m going to show you how to build your own &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; testing framework on top of a vanilla unit testing framework. For my example I’m going to use &lt;a href="http://www.nunit.org/" target="_blank"&gt;NUnit&lt;/a&gt; but I’ve applied the same principles with &lt;a href="http://www.mbunit.com/" target="_blank"&gt;MbUnit&lt;/a&gt;, &lt;a href="http://www.codeplex.com/xunit" target="_blank"&gt;xUnit&lt;/a&gt; and it should work with any other unit testing framework too. &lt;/p&gt;  &lt;p&gt;What’s good about doing things this way, as opposed to using a purpose built BDD framework like &lt;a href="http://github.com/machine/machine.specifications/tree/master" target="_blank"&gt;MSpec&lt;/a&gt;, is that it allows your tests to exist and be run side-by-side with traditional unit tests. This can ease the migration to the new style if you’re all moving over to it and it lets you write tests in the &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; style for some parts of the system whilst sticking with the traditional unit style for other parts. Though I’ll be amazed if you don’t end up writing all your tests in the &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; style as everyone I’ve shown it too loves it.&lt;/p&gt;  &lt;p&gt;I’ll show you how to create the basis for your own &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; framework and I’ll give an example of how a &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; style test looks in comparison to a traditional unit test.&lt;/p&gt;  &lt;h3&gt;What is BDD all about?&lt;/h3&gt;  &lt;p&gt;The core concept of &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; is Given-When-Then (often referred to as Arrange-Act-Assert):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Given&lt;/strong&gt; the system is in a certain state (the context of the test) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;When&lt;/strong&gt; an action is performed on the system (normally calling a single method) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Then&lt;/strong&gt; a list of assertions should be satisfied &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Herein lies another fundamental difference with &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt;, you will create a test fixture per &lt;strong&gt;scenario&lt;/strong&gt; rather than a fixture per class as it common with traditional unit testing.&lt;/p&gt;  &lt;h3&gt;The basis of our framework&lt;/h3&gt;  &lt;p&gt;The way to transform your standard unit testing framework to a &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; one is to use an &lt;strong&gt;abstract base class&lt;/strong&gt;. This will modify how your tests are run, giving you the ability to specify your &lt;strong&gt;Given&lt;/strong&gt;, &lt;strong&gt;When&lt;/strong&gt; and corresponding &lt;strong&gt;Thens&lt;/strong&gt; separately from one another:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixtureSetUp&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Setup()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This means that the contents of your &lt;strong&gt;Given&lt;/strong&gt; and &lt;strong&gt;When&lt;/strong&gt; methods will be run &lt;strong&gt;once&lt;/strong&gt; before each of your methods decorated with the &lt;strong&gt;Test&lt;/strong&gt; attribute are run. This is important as it means that all your assertions should not have side effects (this should be the case already). You will use it in a test class by doing something like this:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; System;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ExampleBehaviour&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// the system is setup in a certain state&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// a defined action is performed on the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ThisAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; AnotherAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Notice that the intent verified by each assertion is documented in the name of the test method. This means that when you run your tests, the name of the tests themselves show you when was meant to happen rather than the error messages that most people forget to add to their assertions.&lt;/p&gt;  &lt;p&gt;Another thing that I like to do but is entirely optional is alias the Test attribute to be able to use a &lt;strong&gt;Then&lt;/strong&gt; attribute with the same behaviour:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ThenAttribute&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;TestAttribute&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This just changes the original example test slightly so it’s more obvious how the Given-When-Then style is being applied:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; System;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ExampleBehaviour&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// the system is setup in a certain state&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// a defined action is performed on the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ThisAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; AnotherAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;h3&gt;Converting a traditional test&lt;/h3&gt;  &lt;p&gt;I’ll start of with what I think to be a pretty standard unit test that I found in the source of &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;[&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; a_change_after_a_creation_results_in_a_new_oject_with_the_same_properties()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; binder = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt;(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;customer&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.BuildObject();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] {&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;}, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; customer = (&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;)binder.BuildObject().Instance;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.Username.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.FirstName.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;As I see it this, like many other traditional unit tests, is already split into the Given-When-Then style logically:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;[&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; a_change_after_a_creation_results_in_a_new_oject_with_the_same_properties()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// Given - the context we are establishing in the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; binder = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt;(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;customer&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.BuildObject();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] {&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;}, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// When - the action we are performing on the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; customer = (&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;)binder.BuildObject().Instance;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// Then - checking the system ends up in the desired state&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.Username.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.FirstName.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;So splitting it physically into the separate sections is not much of a leap:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ChangingAnObjectAfterACreation&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt; binder;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt; customer;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt;(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;customer&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder.BuildObject();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; customer = (&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;) binder.BuildObject().Instance;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; UsernameShouldBeJohnDoe()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt;, customer.Username);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; FirstNameShouldBeJohn()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;, customer.FirstName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I've dropped the use of the assertion extension methods that &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt; was using (I’ll cover how to write those later in the series), but otherwise the actual test code has remained the same.&lt;/p&gt;  &lt;p&gt;The physical separation of the logical parts of the test makes the test easier to follow and the assertions at least as explicit even without the extension methods being used.&lt;/p&gt;  &lt;p&gt;The fact that &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; makes the separation many people already make when writing traditional unit tests more explicit is why I and other people like it. It makes your tests more readable as you can often skim the Given section as that should be conveyed by the name of the entire fixture. That leaves you to see what method is being called and the assertions being made. These are often now more descriptive as they are given a method name.&lt;/p&gt;  &lt;p&gt;If you’ve got any questions, leave a comment and I’ll reply as soon as I can. Do the same if you’ve any related topics you’d like to see covered. I’m planning on covering, mock management, auto-mocking, fluent test extensions and shared contexts.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Related posts&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/08/if-your-code-isn-tested-it-doesn-work.html" target="_blank"&gt;If your code isn't tested it doesn't work&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html" target="_blank"&gt;Test aided development&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-9068096885841795344?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=qWLlsPzO_SM:_DZbimUlnXQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=qWLlsPzO_SM:_DZbimUlnXQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/qWLlsPzO_SM" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9068096885841795344?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9068096885841795344?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/qWLlsPzO_SM/bdd-from-scratch-build-your-own.html" title="BDD from scratch – Build your own framework (Part 1)" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMFRnw8eSp7ImA9WxNTFkU.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-490508894547929906</id><published>2009-08-19T13:53:00.001+01:00</published><updated>2009-08-19T13:53:37.271+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-19T13:53:37.271+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Quality" /><title>If your code isn't tested, it doesn't work</title><content type="html">&lt;p&gt;I test-drive my code. That means, by definition, that each line is covered by at least one test. I know my code works today and tests ensure it still works tomorrow, next week and next year.&lt;/p&gt;  &lt;p&gt;If your code isn't tested you may know it works today, after drawn-out manual testing through each scenario. But what about tomorrow? Are you going to do the manual tests for today's work? Come next week are you going to be performing manual tests for this week's work? Of course you're not, you'd never get anything done.&lt;/p&gt;  &lt;p&gt;By testing your code you are eliminating the majority of emergent bugs as soon as they happen (you are doing continuous integration aren't you?). This means you produce features faster in the medium to long term as you minimise the number of bugs that arise. A win for business as costs are reduced as well as lead time. I don't know about you but I prefer adding features to chasing bugs too. &lt;/p&gt;  &lt;p&gt;If you're not testing, you must enjoy debugging.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-490508894547929906?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=CciCOVlUmD8:zFXFzcumINY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=CciCOVlUmD8:zFXFzcumINY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/CciCOVlUmD8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/490508894547929906?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/490508894547929906?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/CciCOVlUmD8/if-your-code-isn-tested-it-doesn-work.html" title="If your code isn&amp;#39;t tested, it doesn&amp;#39;t work" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/08/if-your-code-isn-tested-it-doesn-work.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIMQX49cSp7ImA9WxJaE00.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3524433336717462490</id><published>2009-08-03T12:54:00.002+01:00</published><updated>2009-08-03T12:56:20.069+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-03T12:56:20.069+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><title>A better domain event raiser</title><content type="html">&lt;p&gt;There was a lot of discussion about domain events at &lt;a href="http://altnetuk.com/"&gt;AltNetUK&lt;/a&gt; around &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee236415.aspx"&gt;Udi Dahan's recent article&lt;/a&gt;. Please read that first so that you’ll know the context of what I’m about to say, I’ll still be here. Might be useful to have them side-by-side.&lt;/p&gt;  &lt;p&gt;I couldn’t help when reading it that the code around event dispatching was quite a mess, with code added in for multiple, distinct scenarios (live and test). This may just have been to help with the formatting of the article, but it leaves a lot to be desired. &lt;/p&gt;  &lt;p&gt;What I’m going to do here is show my refactored version of the code and explain why I think it is better. What I’m going to be doing is utilising the &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern"&gt;strategy pattern&lt;/a&gt; to separate the logic of dispatching events from the action of requesting an event to be dispatched.&lt;/p&gt;  &lt;p&gt;In figure 1 of &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee236415.aspx#id0400104"&gt;the testability section&lt;/a&gt; Udi shows how the DomainEvents class ends up. Here is how mine looks after the refactoring:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b static}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b DomainEvent}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b static}\cf3 {\b  }\cf5 {\b IEventDispatcher}\cf3 {\b  Dispatcher \{ }\cf1 {\b get}\cf3 {\b ; }\cf1 {\b set}\cf3 {\b ; \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b static}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Raise&amp;lt;TEvent&amp;gt;(TEvent eventToRaise) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         Dispatcher.Dispatch(eventToRaise);}\par ??{\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;DomainEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt; Dispatcher { &lt;span style="color: #cc7832"&gt;get&lt;/span&gt;; &lt;span style="color: #cc7832"&gt;set&lt;/span&gt;; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Raise&amp;lt;TEvent&amp;gt;(TEvent eventToRaise) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dispatcher.Dispatch(eventToRaise);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is made possible because I’ve abstracted the dispatching of the event into a separate class implementing the IEventDispatcher interface:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red104\green151\blue187;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b interface}\cf3 {\b  }\cf4 {\b IEventDispatcher}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b void}\cf3 {\b  Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf4 {\b IEvent}\cf3 {\b ;}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;interface&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;There would be two implementations of IEventDispatcher in normal projects. One to be used at runtime such as this one utilising StructureMap:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b StructureMapEventDispatcher}\cf3 {\b  : }\cf5 {\b IEventDispatcher}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         }\cf1 {\b foreach}\cf3 {\b  (}\cf1 {\b var}\cf3 {\b  handler }\cf1 {\b in}\cf3 {\b  }\cf4 {\b ObjectFactory}\cf3 .GetAllInstances&amp;lt;\cf5 {\b IEventHandler}\cf3 &amp;lt;TEvent&amp;gt;&amp;gt;())\par ??{\b         \{}\par ??{\b             handler.Handle(eventToDispatch);}\par ??{\b         \}}\par ??{\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;StructureMapEventDispatcher&lt;/span&gt; : &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;foreach&lt;/span&gt; (&lt;span style="color: #cc7832"&gt;var&lt;/span&gt; handler &lt;span style="color: #cc7832"&gt;in&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;ObjectFactory&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.GetAllInstances&amp;lt;&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IEventHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEvent&amp;gt;&amp;gt;())&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handler.Handle(eventToDispatch);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;And one to be used during unit tests such as this one:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;\red128\green128\blue128;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b ActionEventDispatcher}\cf3 {\b  : }\cf5 {\b IEventDispatcher}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b private}\cf3 {\b  }\cf1 {\b readonly}\cf3 {\b  }\cf5 {\b IDictionary}\cf3 &amp;lt;\cf4 {\b Type}\cf3 {\b , }\cf4 {\b Delegate}\cf3 &amp;gt; handlers;\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  ActionEventDispatcher()}\par ??{\b     \{}\par ??{\b         handlers = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Dictionary}\cf3 &amp;lt;\cf4 {\b Type}\cf3 {\b , }\cf4 {\b Delegate}\cf3 &amp;gt;();\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Register&amp;lt;TEvent&amp;gt;(}\cf5 {\b Action}\cf3 &amp;lt;TEvent&amp;gt; eventAction) \cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         }\cf6 {\b // assuming you'll only register once per test}\par ??\cf3 {\b         handlers.Add(}\cf1 {\b typeof}\cf3 {\b (TEvent), eventAction);}\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         }\cf1 {\b if}\cf3 {\b  (!handlers.ContainsKey(}\cf1 {\b typeof}\cf3 {\b  (TEvent))) }\cf1 {\b return}\cf3 {\b ;}\par ??\par ??{\b         }\cf1 {\b var}\cf3 {\b  handler = (}\cf5 {\b Action}\cf3 &amp;lt;TEvent&amp;gt;) handlers[\cf1 {\b typeof}\cf3 {\b  (TEvent)];}\par ??\par ??{\b         handler.Invoke(eventToDispatch);}\par ??{\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;ActionEventDispatcher&lt;/span&gt; : &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IDictionary&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="color: #ffc66d"&gt;Delegate&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt; handlers;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; ActionEventDispatcher()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handlers = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Dictionary&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="color: #ffc66d"&gt;Delegate&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;();&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Register&amp;lt;TEvent&amp;gt;(&lt;span style="color: #6897bb"&gt;Action&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEvent&amp;gt; eventAction) &lt;/span&gt;&lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: gray"&gt;// assuming you'll only register once per test&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handlers.Add(&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt;(TEvent), eventAction);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;if&lt;/span&gt; (!handlers.ContainsKey(&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt; (TEvent))) &lt;span style="color: #cc7832"&gt;return&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; handler = (&lt;span style="color: #6897bb"&gt;Action&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEvent&amp;gt;) handlers[&lt;/span&gt;&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt; (TEvent)];&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handler.Invoke(eventToDispatch);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;You’ll notice that the two event dispatchers are the two sides that can be executed in Udi’s implementation. That is the essence of the &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern"&gt;strategy pattern&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This does modify the test slightly so that you now have to do this:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red255\green255\blue255;\red39\green39\blue39;\red255\green198\blue109;\red204\green120\blue50;}??\fs20 \cf1\cb2\highlight2 {\b [}\cf3 {\b Test}\cf1 {\b ]}\par ??\cf4 {\b public}\cf1 {\b  }\cf4 {\b void}\cf1 {\b  DoSomethingShouldMakeCustomerPreferred()}\par ??{\b \{}\par ??{\b     }\cf4 {\b var}\cf1 {\b  c = }\cf4 {\b new}\cf1 {\b  }\cf3 {\b Customer}\cf1 {\b ();}\par ??{\b     }\cf3 {\b Customer}\cf1 {\b  preferred = }\cf4 {\b null}\cf1 {\b ;}\par ??\par ??{\b     }\cf4 {\b var}\cf1 {\b  eventDispatcher = }\cf4 {\b new}\cf1 {\b  }\cf3 {\b ActionEventDispatcher}\cf1 {\b ();}\par ??\par ??{\b     }\cf3 {\b DomainEvent}\cf1 .Dispatcher = eventDispatcher;\par ??\par ??{\b     eventDispatcher.Register&amp;lt;}\cf3 {\b CustomerBecamePreferred}\cf1 &amp;gt;\par ??{\b         (p =&amp;gt; preferred = p.Customer);}\par ??\par ??{\b     c.DoSomething();}\par ??{\b     Assert(preferred == c &amp;amp;&amp;amp; c.IsPreferred);}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;[&lt;span style="color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; DoSomethingShouldMakeCustomerPreferred()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; c = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Customer&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Customer&lt;/span&gt; preferred = &lt;span style="color: #cc7832"&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; eventDispatcher = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;ActionEventDispatcher&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;DomainEvent&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Dispatcher = eventDispatcher;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; eventDispatcher.Register&amp;lt;&lt;span style="color: #ffc66d"&gt;CustomerBecamePreferred&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (p =&amp;gt; preferred = p.Customer);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; c.DoSomething();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; Assert(preferred == c &amp;amp;&amp;amp; c.IsPreferred);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I would put the attachment of the ActionEventDispatcher into a test base class so that you didn’t have to set it up for every test, reducing the noise added.&lt;/p&gt;  &lt;p&gt;You would also have to add a small bit of code to hook up your real event dispatcher when your application started:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  SetEventDispatcher()}\par ??{\b \{}\par ??{\b     }\cf4 {\b DomainEvent}\cf3 .Dispatcher = \cf1 {\b new}\cf3 {\b  }\cf4 {\b StructureMapEventDispatcher}\cf3 {\b ();}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; SetEventDispatcher()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;DomainEvent&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Dispatcher = &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;StructureMapEventDispatcher&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Still not sure whether I like the use of domain events or not. However, I did notice this potential refactoring whilst reading the article and thought it was interesting enough to blog about. I think it has left the code in a much better state and I think it also addresses some of the concerns that were raised about the static class at &lt;a href="http://altnetuk.com/"&gt;AltNetUK&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3524433336717462490?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=oY9WOcNQ10E:e-g-BCmAAzA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=oY9WOcNQ10E:e-g-BCmAAzA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/oY9WOcNQ10E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3524433336717462490/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3524433336717462490" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3524433336717462490?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3524433336717462490?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/oY9WOcNQ10E/better-domain-event-raiser.html" title="A better domain event raiser" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/08/better-domain-event-raiser.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QHQHc6eyp7ImA9WxJbFUk.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-9056367122077205045</id><published>2009-07-25T20:15:00.001+01:00</published><updated>2009-07-25T20:15:31.913+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-25T20:15:31.913+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>POST overload – implementation considerations</title><content type="html">&lt;p&gt;As I have &lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;been&lt;/a&gt;&amp;#160;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;blogging&lt;/a&gt;&amp;#160;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/overloading-post-change-of-mind.html"&gt;about&lt;/a&gt;, I’ve been fighting with myself over the best way to implement POST overloading in &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;RESTful ASP.NET MVC&lt;/a&gt;. I’m still not happy that I have chosen the best implementation in using the URL to indicate the overload but I’m done with thinking about it for now. I’m going to record my and others thoughts about the pros and cons of each approach and move on to other functionality.&lt;/p&gt;  &lt;p&gt;The two main points around which the discussion revolves are transparency and adherence to the spirit of HTTP. A compromise has to be made on one of them, which you choose to compromise, I feel, is a personal decision.&lt;/p&gt;  &lt;p&gt;Using a hidden form value for overloading is transparent to the user, the URL the POST is made to does not change. My &lt;a href="http://blog.robustsoftware.co.uk/2009/07/overloading-post-change-of-mind.html"&gt;previous argument&lt;/a&gt; for needing to implement overloading for different content types is nonsense as you would never need to use POST overloading apart from when POSTing a form from a browser. All other calls will be able to use the correct HTTP verb directly.&lt;/p&gt;  &lt;p&gt;The URL overloading method, for me, remains closer to the spirit of HTTP. If the URL contains the overload you know how to handle the request purely from the head of the HTTP request. Using the form value method you need to check the body of the HTTP request to know what to do.&lt;/p&gt;  &lt;p&gt;Neither method is ideal, they both have their compromises and I can’t honestly say whether one is better than the other at the moment. Perhaps I’ll obtain some insight later that makes one clearly better than the other. However, I do know that at the moment I’m risking the wrath of &lt;a href="http://blog.scottbellware.com/"&gt;Scott Bellware&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://twitter.com/gshutler"&gt;@gshutler&lt;/a&gt; ultimately, i'm gonna come gunning for you if this hack-in-the-uri becomes convention in the late-to-the-game .net rest users :) &lt;a href="http://twitter.com/bellware/statuses/2828993797"&gt;Sat 25 Jul 01:20&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If you find me in a ditch because everyone starts using the URL overload method, you have a prime suspect.&lt;/p&gt;  &lt;p&gt;I’d like to thank &lt;a href="http://twitter.com/bellware"&gt;Scott Bellware&lt;/a&gt; and &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt; for taking the time to talk to me about this subject over the past couple of weeks on twitter, it’s greatly appreciated.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-9056367122077205045?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=kTd3zbfHRSE:41fIUyTUQCc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=kTd3zbfHRSE:41fIUyTUQCc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/kTd3zbfHRSE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/9056367122077205045/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=9056367122077205045" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9056367122077205045?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9056367122077205045?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/kTd3zbfHRSE/post-overload-implementation.html" title="POST overload – implementation considerations" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/post-overload-implementation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUCR3k9eCp7ImA9WxJbFkU.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-5217201963277999827</id><published>2009-07-24T21:52:00.005+01:00</published><updated>2009-07-27T09:11:06.760+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-27T09:11:06.760+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>Overloading POST – a change of mind</title><content type="html">&lt;p&gt;Today I made a fairly fundamental change in design of &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;RESTful ASP.NET MVC&lt;/a&gt; revolving around how I will be overloading post for HTML forms. &lt;/p&gt;  &lt;p&gt;Previously I was adding a hidden field to the form, which is how it is done by Rails:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre style="line-height: 1.1em"&gt;&amp;lt;form method="POST" action="/Users/2"&amp;gt;&lt;br /&gt;&amp;lt;input value="DELETE" type="hidden" name="_method" /&amp;gt;&lt;br /&gt;&amp;lt;input value="Delete" type="submit" /&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt; &lt;/blockquote&gt; &lt;p&gt;I was aware of &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta's&lt;/a&gt; method of overloading post which is to append the overload to the URI:&lt;/p&gt; &lt;blockquote&gt;   &lt;pre style="line-height: 1.1em"&gt;&amp;lt;form method="POST" action="/Users/2!DELETE"&amp;gt;&lt;br /&gt;&amp;lt;input value="Delete" type="submit" /&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt; &lt;/blockquote&gt; &lt;p&gt;However, I didn’t like the way the overload was opaque to the user and thinking that the Rails guys must have thought about it a fair bit I initially went with the former method.&lt;/p&gt; &lt;p&gt;I ended up having a discussion with &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt;, the developer of &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;, about the two options and why he had chosen the second method over the first (I love twitter for this). To be honest, I came away from the discussion thinking there wasn’t much to chose between the two, it just being down to a matter of preference. However, I kept thinking about it, questioning my decision and whether it my choice really was better than the other option.&lt;/p&gt;  &lt;p&gt;&lt;strike&gt;I had a moment of clarity whilst playing golf. I realised that, potentially, I might have to write post overload mechanisms for multiple formats as clients could submit requests in a variety of formats (XML, JSON, form, etc). If the overload is contained within the URL then the overload is independent of the body’s content type, simplifying things considerably.&lt;/strike&gt;&lt;/p&gt; &lt;p&gt;Now I had a reason to change, I did so, changing &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;RESTful ASP.NET MVC’s&lt;/a&gt; method of overloading post to the URI mechanism. As it happens this tidied up the code a little as I no longer had to pass around the form collection, I could work purely off the routing values.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;RESTful ASP.NET MVC&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;REST - a quick summary&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You should &lt;a href="http://feeds2.feedburner.com/RobustSoftware"&gt;subscribe to my feed to keep up with development of RESTful ASP.NET MVC.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;UPDATE&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I have written a &lt;a href="http://blog.robustsoftware.co.uk/2009/07/post-overload-implementation.html"&gt;follow-up post about the implementation considerations for POST overload&lt;/a&gt; that I recommend reading as well.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-5217201963277999827?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=neGSm4yuB8A:1rs0GfjHVsQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=neGSm4yuB8A:1rs0GfjHVsQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/neGSm4yuB8A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/5217201963277999827/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=5217201963277999827" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/5217201963277999827?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/5217201963277999827?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/neGSm4yuB8A/overloading-post-change-of-mind.html" title="Overloading POST – a change of mind" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/overloading-post-change-of-mind.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEGSHg5eip7ImA9WxJUGUk.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3798571875403165157</id><published>2009-07-18T21:21:00.001+01:00</published><updated>2009-07-18T21:23:49.622+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-18T21:23:49.622+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Extension methods" /><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>ASP.NET MVC Route Testing with HTTP Verbs</title><content type="html">&lt;p&gt;I’ve started &lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;RESTful ASP.NET MVC&lt;/a&gt; from scratch and I am test-driving it. Writing code without tests is ok for proofs of concept but as I was planning on continually adding to the project I felt I had to start again and make sure everything was tested. As part of the process I was looking to test my routing rules. I used &lt;a href="http://haacked.com/archive/2007/12/17/testing-routes-in-asp.net-mvc.aspx"&gt;Phil Haack’s route testing helper&lt;/a&gt; as a starting point but I think I’ve customised it enough to warrant a post.&lt;/p&gt;  &lt;p&gt;The first thing I did was change his static method into an extension method. However, my routes were also dependant upon the HTTP verb used so I had to add that in on top. I also needed to check that a route wouldn’t be matched for the same reason as a URI which is valid for a GET may not be valid for a POST.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/branches/testdriven/code/RestfulMVC.Test/RouteTestHelper.cs?r=5"&gt;My route test helper&lt;/a&gt; and &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/branches/testdriven/code/RestfulMVC.Test/Routes/WhenRoutesHaveBeenRegistered.cs?r=5"&gt;an example of it in action&lt;/a&gt; from the test-driven branch of &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;restful-aspmvc&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Related posts&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;RESTful ASP.NET MVC&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;REST - a quick summary&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3798571875403165157?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Hv_i8HiR0yg:p2vjRRr2C88:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Hv_i8HiR0yg:p2vjRRr2C88:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Hv_i8HiR0yg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3798571875403165157/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3798571875403165157" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3798571875403165157?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3798571875403165157?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Hv_i8HiR0yg/aspnet-mvc-route-testing-with-http.html" title="ASP.NET MVC Route Testing with HTTP Verbs" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/aspnet-mvc-route-testing-with-http.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMESXYzeCp7ImA9WxJUGE4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-7211204304122845686</id><published>2009-07-17T13:11:00.001+01:00</published><updated>2009-07-17T13:23:28.880+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-17T13:23:28.880+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>RESTful ASP.NET MVC</title><content type="html">&lt;p&gt;This is the first in what could be a series of posts on how to modify the internals of ASP.NET MVC in order to make it work in a more RESTful manner. If you want to work with a RESTful web framework built on .NET today then I recommend using &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The reason I’m doing this is two-fold:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;I want to learn more about REST beyond &lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;the theory&lt;/a&gt; and I learn more by doing. &lt;/li&gt;&lt;li&gt;Sometimes it’s impossible to convince people to use an open source framework like &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;, but customising stuff produced by Microsoft is much better received. I hope this will help other people write more RESTful sites whilst using Microsoft-based frameworks. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;All the code I will be referring to is available on the &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;restful-aspmvc project page&lt;/a&gt;. At the time of writing this the code was on &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/?r=3"&gt;revision 3&lt;/a&gt;, so if you are reading this later on there my be some inconsistencies.&lt;/p&gt;&lt;h4&gt;The inspiration&lt;/h4&gt;&lt;p&gt;I wanted to be able to use RESTful URLs like those available in Ruby on Rails. These work by selecting the controller action through the use of the URL &lt;strong&gt;and&lt;/strong&gt; the HTTP verb.&lt;/p&gt;&lt;pre&gt;GET /users/               UsersController.Index()&lt;/pre&gt;&lt;pre&gt;POST /users/              UsersController.Create()&lt;/pre&gt;&lt;pre&gt;GET /users/{id}           UsersController.Show(id)&lt;/pre&gt;&lt;pre&gt;PUT /users/{id}           UsersController.Update(id)&lt;/pre&gt;&lt;pre&gt;DELETE /users/{id}        UsersController.Destroy(id)&lt;/pre&gt;&lt;p&gt;I then wanted to allow you to create different views of the resources by specifying other actions that can only use the GET verb like so:&lt;/p&gt;&lt;pre&gt;GET /users/{action}       UsersController.{Action}()&lt;/pre&gt;&lt;pre&gt;GET /users/{id}/{action}  UsersController.{Action}(id)&lt;/pre&gt;&lt;h4&gt;The implementation&lt;/h4&gt;&lt;p&gt;The above routes are achieved through these route mappings: &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/trunk/RESTfulMVC/Global.asax.cs?r=3"&gt;listing on Google code&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The next problem was to map to the different actions according to the URL and the HTTP verb. As web browsers only support GET and POST this requires a technique known as overloading POST. I tried doing this in a couple of ways, firstly by including the required HTTP verb in the URL:&lt;/p&gt;&lt;blockquote&gt; &lt;pre&gt;/users/{id}?verb=DELETE&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;However, I found this quite ugly. As we are overloading POST, there will always be a form involved, therefore I’ve specified the required verb (where necessary) with a hidden form field:&lt;/p&gt;&lt;blockquote&gt; &lt;pre style="line-height: 1.1em"&gt;&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;/Users/2&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;input value=&amp;quot;DELETE&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;_verb&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;        &lt;br /&gt;        &amp;lt;input value=&amp;quot;Delete&amp;quot; type=&amp;quot;submit&amp;quot; /&amp;gt;        &lt;br /&gt;    &amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Now the verb is specified in the form, we have our URLs working we now need to act on this information. For that I have used a customer controller factory (&lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/trunk/RESTfulMVC/RestfulControllerFactory.cs?r=3"&gt;Google code listing&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;There’s a fair bit of code to include directly into a blog post so I’ll explain the general flow to you and if you’re interested in the implementation you can have a look at the listing.&lt;/p&gt;&lt;ol&gt; &lt;li&gt;When the controller is created we use the default implementation to retrieve the controller and give it a custom action invoker to use. &lt;/li&gt;  &lt;li&gt;When the action is invoked we first check if the verb being used is a POST, if it is we check the form for an override. If one exists we change what we think the HTTP verb is to the one passed. &lt;/li&gt;  &lt;li&gt;If no specific action has been used (the default action is Index because of the routes we specified) then we use the HTTP verb and whether an id was specified to determine the actual action required. &lt;/li&gt;  &lt;li&gt;We use the default implementation to invoke the action required. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/?r=3"&gt;full code listing&lt;/a&gt; includes a basic site which shows all the overrides being used along with a couple of common custom views (new and edit are commonly used to display forms to create and update resources).&lt;/p&gt;&lt;p&gt;This is the first step towards making ASP.NET MVC more RESTful. I welcome your comments and feedback, especially if there is something in particular you’d like me to implement in the future.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-7211204304122845686?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=N75mF0ZjCm0:ZHCh6T31ttw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=N75mF0ZjCm0:ZHCh6T31ttw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/N75mF0ZjCm0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/7211204304122845686/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=7211204304122845686" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7211204304122845686?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7211204304122845686?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/N75mF0ZjCm0/restful-aspnet-mvc.html" title="RESTful ASP.NET MVC" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IGSH8-eyp7ImA9WxJUFE8.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4446578865332214108</id><published>2009-07-12T19:28:00.001+01:00</published><updated>2009-07-12T21:12:09.153+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-12T21:12:09.153+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><title>REST – a quick summary</title><content type="html">&lt;p&gt;I’d read a lot of blogs talking about REST and it’s benefits but I hadn’t fully got it. Whilst on holiday I read &lt;a href="http://www.amazon.co.uk/RESTful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1247417574&amp;amp;sr=8-1"&gt;RESTful Web Services&lt;/a&gt;, which I had seen recommended, in an effort to try and finally grok REST. &lt;/p&gt;  &lt;p&gt;I thoroughly recommend this book, it helped me connect a lot of previously separate ideas into a coherent whole. What I hope to do here is give an overview of what I’ve learnt from the book to act as a reference to myself and maybe help other people in the process.&lt;/p&gt;  &lt;h4&gt;Definition&lt;/h4&gt;  &lt;p&gt;REST is short for &lt;strong&gt;Representational State Transfer&lt;/strong&gt;. Distilled down, it’s basically about using the &lt;strong&gt;HTTP verbs&lt;/strong&gt;, &lt;strong&gt;GET&lt;/strong&gt;, &lt;strong&gt;POST&lt;/strong&gt;, &lt;strong&gt;PUT&lt;/strong&gt;, &lt;strong&gt;DELETE&lt;/strong&gt; and &lt;strong&gt;HEAD&lt;/strong&gt;, in order to act on &lt;strong&gt;resources&lt;/strong&gt;, represented by individual URIs.&lt;/p&gt;  &lt;p&gt;Resources are &lt;em&gt;similar&lt;/em&gt; to what most of you will think of as domain entities. However, a relationship between two entities can be represented by a resource.&lt;/p&gt;  &lt;h4&gt;Underlying principle&lt;/h4&gt;  &lt;p&gt;The main idea behind REST is that you are working with the HTTP protocol. Other web service ideas like SOAP, referred to in the book as Big Web Services, mostly ignore the expressiveness of the HTTP protocol and use only GET and/or POST requests. This often works against the HTTP protocol, at best it ignores .&lt;/p&gt;  &lt;p&gt;The requests and responses of the HTTP protocol consist of a &lt;strong&gt;head&lt;/strong&gt; and a &lt;strong&gt;body&lt;/strong&gt;. The analogy used in the book is one of an envelope, the head being the envelope and the body being the contents of the envelope. REST uses the URI, HTTP verbs, HTTP headers and HTTP response codes in order to communicate to the server what is wanted and to the client what happened.&lt;/p&gt;  &lt;p&gt;This is in contrast to SOAP which generally uses the URI from the head and then sends another envelope in the body to communicate more information about the request to the server and the response to the client. This is effectively putting an envelope inside another envelope.&lt;/p&gt;  &lt;h4&gt;HTTP verbs and their meanings&lt;/h4&gt;  &lt;p&gt;The beauty of the verbs are that they are mostly self-explanatory, but I’ll explain all of them for completeness.&lt;/p&gt;  &lt;h5&gt;GET&lt;/h5&gt;  &lt;p&gt;This verb means give me the current representation for the given URI. You can use headers to modify the behaviour slightly. For example, the &lt;strong&gt;If-Modified-Since&lt;/strong&gt; header can be used to say “only send me the representation for the URI if it has changed since the given date”. This can be used to minimize needless traffic and processing.&lt;/p&gt;  &lt;h5&gt;DELETE&lt;/h5&gt;  &lt;p&gt;This verb means delete the representation at the given URI. There’s not really anything complicated about it.&lt;/p&gt;  &lt;h5&gt;HEAD&lt;/h5&gt;  &lt;p&gt;This is equivalent to a GET request but only returns the HEAD of the response, omitting the BODY. This is used for getting the meta data about a resource, for example checking whether a resource exists at a given URI without retrieving the BODY as well.&lt;/p&gt;  &lt;h5&gt;POST and PUT&lt;/h5&gt;  &lt;p&gt;I’ve put these two together as they are the ones I previously had most difficulty differentiating between. Needless to say the book explained the difference perfectly.&lt;/p&gt;  &lt;p&gt;PUT is used to place a resource to a &lt;em&gt;specific&lt;/em&gt; URI (eg. /Product/1), this can be a resource that didn’t exist before (an insert) or replace the existing representation at that URI (an update). In contrast, POST is used to add a resource to the end of a list of resources (eg. /Product) when you don’t know the URI in advance (an insert). Once you know the URI of your new resource, you will use a PUT to update it.&lt;/p&gt;  &lt;h4&gt;REST and HTML forms&lt;/h4&gt;  &lt;p&gt;A problem I had was reuse of web service code with web sites, HTML only supports the verbs GET and POST. I was concerned about having to maintain two sets of code for acting on the same resources. This can be overcome by using a concept called &lt;strong&gt;overloaded post&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;The idea behind it is really simple, you include the verb you want to use as a query string parameter and POST to that URI (eg. /Product/1?method=DELETE). Then using some simple server-side code you handle the request as the verb passed instead of as a POST.&lt;/p&gt;  &lt;h4&gt;Conclusion&lt;/h4&gt;  &lt;p&gt;I’ve covered the main concepts that helped me understand the big picture of REST. I really think it is the best way to write web services so that they can be easily consumed by other people. The emphasis of REST is on simplicity, utilising the power of the HTTP protocol rather than building a new protocol on top of it. This goes against the common practice up until this point, which to me is a breath of fresh air.&lt;/p&gt;  &lt;p&gt;Finally, I strongly recommend you buy &lt;a href="http://www.amazon.co.uk/RESTful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1247417574&amp;amp;sr=8-1"&gt;the book&lt;/a&gt; if you are interested in learning more about REST.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4446578865332214108?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=cWajBYqCYR4:IMQ1I90MAMc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=cWajBYqCYR4:IMQ1I90MAMc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/cWajBYqCYR4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/4446578865332214108/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=4446578865332214108" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4446578865332214108?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4446578865332214108?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/cWajBYqCYR4/rest-quick-summary.html" title="REST – a quick summary" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIGRHYzfSp7ImA9WxJUEkk.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-9060546616244980864</id><published>2009-07-10T18:55:00.001+01:00</published><updated>2009-07-10T18:55:25.885+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-10T18:55:25.885+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>Nott Tuesday and the altnetbeers format</title><content type="html">&lt;p&gt;As &lt;a href="http://blog.robustsoftware.co.uk/2009/06/nott-tuesday-july-14th.html"&gt;I said previously&lt;/a&gt; I’ve volunteered to lead this month’s &lt;a href="http://notttuesday.com/"&gt;Nott Tuesday&lt;/a&gt; event, taking place this coming Tuesday, 14th July.&lt;/p&gt;  &lt;p&gt;So, as promised, I’m going to give the outline of how the whole evening will work. Hopefully it will encourage more participation from the whole group in the discussion, improving the night for everyone.&lt;/p&gt;  &lt;h4&gt;Topic selection&lt;/h4&gt;  &lt;p&gt;So a little while after 18:30, once everyone has had the chance to say hellos and so forth, I’ll ask everyone to volunteer topics for discussion. I’ll provide a stack of index cards and pens and anyone who has something they’d like to talk about can write a question on a card and put it onto a table for others to see. Something as vague as “why agile?” or specific as “how do I leverage e-marketing to obtain new business?” is fine. Framing it as a question will probably work better, but if you can’t do that then a simple sentence will do. The idea is to give the group a starting point for a discussion.&lt;/p&gt;  &lt;p&gt;Once we’ve had 5-10 minutes to write down our ideas we will whittle them down to the few most popular topics by voting on the ideas as a group. We’ll start off with the most popular topic and if the discussion is lively enough for long enough that might be all we discuss all night but if things start tailing off we’ll move on to the next most popular topic.&lt;/p&gt;  &lt;h4&gt;How does the discussion work?&lt;/h4&gt;  &lt;p&gt;There will be a “bench” where 3 people sit, they are the panel of which the group can ask questions. To begin with I’ll ask whichever person raised the topic to speak for 30 seconds or so just to explain a bit further what they want to get from the discussion. This person will also start off on the bench along with 2 volunteers. It is then thrown to the floor to ask questions of the bench. If you have a question, raise your hand and I’ll pick a person at a time to ask their question to stop it being a free-for-all. If you are part of the audience, you can only ask questions or come back on the answers given by the panel when applicable. &lt;/p&gt;  &lt;p&gt;If it is a topic you are interested in and have something to say about it, you can go and sit in the “hot seat”, this signifies you want to be on the bench and answer questions. When someone is in the hot seat, someone from the bench is obliged to return to the audience, allowing the person in the hot seat to move onto the bench. This can manage itself by people not having more to say or wanting a break, but if not we’ll do it on a first-in-first-out basis.&lt;/p&gt;  &lt;h4&gt;A personal plea&lt;/h4&gt;  &lt;p&gt;Please be gentle with me, it’s the first time I’ve run something like this so bear with me a bit. I might need to cut you off if you’re in the middle of a heated discussion but the majority of the room looks bored, please bear in mind I’m trying to keep it interesting for the whole group. There’s nothing to stop your carrying on the discussion afterwards of course!&lt;/p&gt;  &lt;p&gt;That’s all there is to it really. Hopefully, it will result in an enjoyable evening for everyone, having lively discussions about topics we’re all interested in.&lt;/p&gt;  &lt;p&gt;See you at &lt;a href="http://maps.google.co.uk/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=5+Broadway,+Nottingham,+NG1+1PR&amp;amp;sll=52.951968,-1.143397&amp;amp;sspn=0.008507,0.017273&amp;amp;gl=uk&amp;amp;ie=UTF8&amp;amp;z=16&amp;amp;iwloc=A"&gt;Bluu&lt;/a&gt; on Tuesday 14th July at 18:30!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-9060546616244980864?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=5ZJDZGfNBX4:cSltcWZiwwU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=5ZJDZGfNBX4:cSltcWZiwwU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/5ZJDZGfNBX4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/9060546616244980864/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=9060546616244980864" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9060546616244980864?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9060546616244980864?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/5ZJDZGfNBX4/nott-tuesday-and-altnetbeers-format.html" title="Nott Tuesday and the altnetbeers format" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/nott-tuesday-and-altnetbeers-format.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cDQ3k_eyp7ImA9WxJWGU4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4833588362135594986</id><published>2009-06-25T12:57:00.001+01:00</published><updated>2009-06-25T12:57:52.743+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-25T12:57:52.743+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notttuesday" /><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>Nott Tuesday – July 14th</title><content type="html">&lt;p&gt;So I went to &lt;a href="http://notttuesday.com/"&gt;Nott Tuesday&lt;/a&gt; for the first time last month and really enjoyed it. &lt;a href="http://twitter.com/adambird"&gt;Adam Bird&lt;/a&gt;, the guy who started it up seemed keen to move towards group discussion rather than one or two people presenting to the group.&lt;/p&gt;  &lt;p&gt;I’d been to a similar event before, &lt;a href="http://ukdotnet.ning.com/events/london-altnetbeers-8"&gt;altnetbeers&lt;/a&gt;, which is run by &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt; in London. Altnetbeers had the sort of group discussion I felt Adam was looking for so I dropped him an email the next day explaining the format to see what he though.&lt;/p&gt;  &lt;p&gt;Well I should have known better because, as &lt;a href="http://notttuesday.com/2009/06/25/tuesday-july-14th-something-a-little-different/"&gt;has now been announced&lt;/a&gt;, Adam said he liked the sound of it and asked me if I wanted to lead the next meeting in the style of altnetbeers. I couldn’t well say no after telling him how great it was so here we are.&lt;/p&gt;  &lt;p&gt;I’ll be cross posting an explanation of how it all works a bit nearer the time so that people will have an idea of what will be happening on the night.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4833588362135594986?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=M_JYUqU7IGQ:7kso2h8-HIE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=M_JYUqU7IGQ:7kso2h8-HIE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/M_JYUqU7IGQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/4833588362135594986/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=4833588362135594986" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4833588362135594986?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4833588362135594986?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/M_JYUqU7IGQ/nott-tuesday-july-14th.html" title="Nott Tuesday – July 14th" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/06/nott-tuesday-july-14th.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ECQ30zeyp7ImA9WxJWEk4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3050076459776338295</id><published>2009-06-17T12:54:00.001+01:00</published><updated>2009-06-17T12:54:22.383+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-17T12:54:22.383+01:00</app:edited><title>Opening a Command Prompt for the solution in Visual Studio</title><content type="html">&lt;p&gt;Something I’ve found myself needing to do more recently is open a command prompt at the root directory of my solution. Often this is to run a rake task or something like that.&lt;/p&gt;  &lt;p&gt;The way I used to do this was rather long winded, but now I’ve got it down to a single key combination and I’ll explain here how you can do the same.&lt;/p&gt;  &lt;p&gt;Firstly, open up the external tools dialog in Visual Studio:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_menu" border="0" alt="externaltools_menu" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZXHNyxlI/AAAAAAAAACM/3Vi790QDVSk/externaltools_menu%5B6%5D.png?imgmax=800" width="536" height="747" /&gt;&lt;/p&gt;  &lt;p&gt;Then add a new tool:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_add" border="0" alt="externaltools_add" src="http://lh4.ggpht.com/_GAonj6z3iqg/SjjZXlxVqgI/AAAAAAAAACQ/KrdV1TiZ7WE/externaltools_add%5B5%5D.png?imgmax=800" width="465" height="452" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This will give you a prompt to type the details of the new tool into:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_adddialog" border="0" alt="externaltools_adddialog" src="http://lh5.ggpht.com/_GAonj6z3iqg/SjjZX0aFJqI/AAAAAAAAACU/6VO1WzuWXKo/externaltools_adddialog%5B2%5D.png?imgmax=800" width="465" height="452" /&gt; &lt;/p&gt;  &lt;p&gt;Then fill in the details of the new tool. We want to point this at cmd.exe which is usually located in your System32 directory. You also want to set the initial directory to the solution directory: &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_solution" border="0" alt="externaltools_solution" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZYVhh10I/AAAAAAAAACY/AvDa0S37jfc/externaltools_solution%5B2%5D.png?imgmax=800" width="724" height="551" /&gt; &lt;/p&gt;  &lt;p&gt;I have then moved the tool up the list just because I like it being higher. The position of the tool in the list only makes a difference when setting up a keyboard shortcut as I will explain in a minute:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_moveup" border="0" alt="externaltools_moveup" src="http://lh5.ggpht.com/_GAonj6z3iqg/SjjZY0IRl9I/AAAAAAAAACc/kQNUxFvHUbo/externaltools_moveup%5B5%5D.png?imgmax=800" width="465" height="452" /&gt; &lt;/p&gt;  &lt;p&gt;Once you’ve filled in all the details and moved the tool to the position you want it in just click Ok. You will now see that the tool you just created appears in the external tools section of the tools menu:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltool_in_menu" border="0" alt="externaltool_in_menu" src="http://lh4.ggpht.com/_GAonj6z3iqg/SjjZZYRSxCI/AAAAAAAAACg/Dps8keGEZm0/externaltool_in_menu%5B2%5D.png?imgmax=800" width="492" height="749" /&gt;&lt;/p&gt;  &lt;p&gt;Now we can set up a keyboard shortcut for the new tool. Firstly, open the options dialog:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tools_options" border="0" alt="tools_options" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZZwYLWYI/AAAAAAAAACk/qCXs0707s64/tools_options%5B2%5D.png?imgmax=800" width="486" height="735" /&gt; &lt;/p&gt;  &lt;p&gt;Then go to the keyboard section:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="options_keyboard" border="0" alt="options_keyboard" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZaXMFz2I/AAAAAAAAACo/sf54FbJ2h80/options_keyboard%5B2%5D.png?imgmax=800" width="751" height="432" /&gt; &lt;/p&gt;  &lt;p&gt;Then type in the command name “Tools.ExternalCommandX” where X is the number your tool appears in the list. Mine is second so I type “2”:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tools_keyboard_externalcommand2" border="0" alt="tools_keyboard_externalcommand2" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZa49P8MI/AAAAAAAAACs/B2-E5NTnJh4/tools_keyboard_externalcommand2%5B2%5D.png?imgmax=800" width="751" height="432" /&gt; &lt;/p&gt;  &lt;p&gt;Then assign a key combination to this command. I chose Ctrl+Shift+Alt+C:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tools_keyboard_assign" border="0" alt="tools_keyboard_assign" src="http://lh6.ggpht.com/_GAonj6z3iqg/SjjZbWmoU-I/AAAAAAAAACw/sWotLdz5xw8/tools_keyboard_assign%5B2%5D.png?imgmax=800" width="751" height="432" /&gt; &lt;/p&gt;  &lt;p&gt;Then click ok and you will now be able to open a command prompt at the root of the current solution with your key combination.&lt;/p&gt;  &lt;p&gt;This principle can be extended to call any program, you may have noticed I use it to call the default rake task for my solution.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3050076459776338295?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=sYXxkPVrGgU:VWbJ0m00Bdc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=sYXxkPVrGgU:VWbJ0m00Bdc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/sYXxkPVrGgU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3050076459776338295/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3050076459776338295" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3050076459776338295?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3050076459776338295?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/sYXxkPVrGgU/opening-command-prompt-for-solution-in.html" title="Opening a Command Prompt for the solution in Visual Studio" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/06/opening-command-prompt-for-solution-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAERn8-eSp7ImA9WxJRE0Q.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-2879189448286727930</id><published>2009-05-15T14:05:00.001+01:00</published><updated>2009-05-15T14:05:07.151+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-15T14:05:07.151+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>Establishing Team Values</title><content type="html">&lt;p&gt;One of the biggest things I took from the Progressive .NET tutorials was the idea of establishing a set of values for your team.&lt;/p&gt;  &lt;p&gt;This was raised in &lt;a href="http://codebetter.com/blogs/david_laribee/"&gt;David Laribee’s&lt;/a&gt; session &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/towards-a-new-architect"&gt;Towards A New Architect&lt;/a&gt; (watch out for the video of that coming out) where he asked whose team had a set of common values. In a room of 30 or so people, I think 3 or 4 raised their hand.&lt;/p&gt;  &lt;p&gt;As soon as it was mentioned it made sense to me. A shared identity and core set of values can only benefit a team. To that end I’m going to run a similar session to the one I participated in in order to establish a set of values for my team.&lt;/p&gt;  &lt;p&gt;I thought I might share the format I’m going to use so that others might do the same:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Set up a 1 hour session for discovering your team’s values &lt;/strong&gt;&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;5 minutes explaining what we are doing and what we want to achieve&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;bring common values to the fore &lt;/li&gt;    &lt;li&gt;give a common identity to the team &lt;/li&gt;    &lt;li&gt;create a catalyst for improvement &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;DIVERGE, CONVERGE, SYNTHESIZE&lt;/strong&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;5 minutes writing words or short phrases down &lt;/li&gt;    &lt;li&gt;5 minutes converging to write all the different phrases on the board by going round the group &lt;/li&gt;    &lt;li&gt;2 minutes dot voting &lt;/li&gt;    &lt;li&gt;1 minute selecting top 3-5 by votes &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;DIVERGE, CONVERGE, SYNTHESIZE&lt;/strong&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;10 minutes to write a sentence explaining why each phrase is important (each person doesn't have to do each one) &lt;/li&gt;    &lt;li&gt;10 minutes coming together, taking each word in turn and sharing sentences all written on the board &lt;/li&gt;    &lt;li&gt;2 minutes tweaking and eliminating duplicates &lt;/li&gt;    &lt;li&gt;2 minutes dot voting each group of sentences &lt;/li&gt;    &lt;li&gt;select the favourite sentence for each phrase&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Your team now has a set of common values &lt;/p&gt;  &lt;p&gt;Thank the team and tell them you are going to get them printed to put up on the wall. The important thing is that they are visible and prominent. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Important points&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;the number of values should be low – the messages should be simple and strong&lt;/li&gt;    &lt;li&gt;the values should be visible to the whole team, all the time&lt;/li&gt;    &lt;li&gt;everyone should be empowered to act to strengthen the values&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I’ll blog about what values my team at &lt;a href="http://www.openprojects.co.uk/"&gt;Open Projects&lt;/a&gt; have chosen next week.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-2879189448286727930?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=s1Lr66_OtoQ:FeMikyXq5gc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=s1Lr66_OtoQ:FeMikyXq5gc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/s1Lr66_OtoQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/2879189448286727930/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=2879189448286727930" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/2879189448286727930?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/2879189448286727930?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/s1Lr66_OtoQ/establishing-team-values.html" title="Establishing Team Values" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/establishing-team-values.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcGQH08cSp7ImA9WxJREkQ.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3252730160782739063</id><published>2009-05-14T11:46:00.000+01:00</published><updated>2009-05-14T11:47:01.379+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-14T11:47:01.379+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Replication" /><title>Great replication troubleshooting article</title><content type="html">&lt;p&gt;I found &lt;a href="http://www.sqlservercentral.com/articles/Replication/61891/"&gt;this article on troubleshooting replication woes&lt;/a&gt;, unfortunately it requires you to sign up for SQL Server Central. However, if you have the “pleasure” of dealing with replication it gives a lot of good pointers on sorting out problems so it’s worth it.&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/04/sql-server-2005-replication-errors.html"&gt;SQL Server 2005 replication errors table&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3252730160782739063?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=52Ta3asPL0Y:RZzijwPvrwA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=52Ta3asPL0Y:RZzijwPvrwA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/52Ta3asPL0Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3252730160782739063/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3252730160782739063" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3252730160782739063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3252730160782739063?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/52Ta3asPL0Y/great-replication-troubleshooting.html" title="Great replication troubleshooting article" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/great-replication-troubleshooting.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYHQ344fCp7ImA9WxJREkQ.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-7435359942004868459</id><published>2009-05-14T09:35:00.001+01:00</published><updated>2009-05-14T09:35:32.034+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-14T09:35:32.034+01:00</app:edited><title>When geek rockstars go wild</title><content type="html">&lt;p&gt;Ok, a silly one but I’ve got to share this. When walking to the hotel on Sunday before Progressive .NET I saw this in &lt;a href="http://maps.google.co.uk/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=A201%2FActon+St&amp;amp;sll=51.528017,-0.117159&amp;amp;sspn=0.005273,0.009313&amp;amp;ie=UTF8&amp;amp;ll=51.528557,-0.117352&amp;amp;spn=0.010546,0.018625&amp;amp;z=16&amp;amp;iwloc=A"&gt;the middle of the pavement&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GAonj6z3iqg/SgvX0FHVjPI/AAAAAAAAACE/oB1usgwbeEA/s1600-h/photo%5B12%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="smashed monitor" border="0" alt="smashed monitor" src="http://lh5.ggpht.com/_GAonj6z3iqg/SgvX02g6igI/AAAAAAAAACI/GPmXWTv2Mk0/photo_thumb%5B10%5D.jpg?imgmax=800" width="380" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’m guessing someone broke the build and this is what happened to their monitor.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-7435359942004868459?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Buga-QWBtd4:TDfCsLvHHNw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Buga-QWBtd4:TDfCsLvHHNw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Buga-QWBtd4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/7435359942004868459/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=7435359942004868459" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7435359942004868459?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7435359942004868459?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Buga-QWBtd4/when-geek-rockstars-go-wild.html" title="When geek rockstars go wild" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/when-geek-rockstars-go-wild.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQFQHY7fyp7ImA9WxJSGEQ.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3661595485405296346</id><published>2009-05-09T19:21:00.001+01:00</published><updated>2009-05-09T19:21:51.807+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-09T19:21:51.807+01:00</app:edited><title>Progressive .NET Tutorials</title><content type="html">&lt;p&gt;I will be attending &lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-exchange"&gt;the Progressive .NET Tutorials&lt;/a&gt; next week and I must say I’m looking forward to it. It’s slightly disappointing that &lt;a href="http://blog.scottbellware.com/"&gt;Scott Bellware&lt;/a&gt; couldn’t make it for his testing track on Monday but there’s plenty of other things going on. This is my plan for the week:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Sunday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Travelling down from Nottingham with &lt;a href="http://www.muonlab.com/"&gt;Andrew Bullock&lt;/a&gt; and checking into the Farringdon Travelodge down the road from &lt;a href="http://skillsmatter.com/"&gt;Skills Matter&lt;/a&gt;. Nothing planned for this evening, probably get something to eat and then hit the hay before a busy few days.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Monday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Going to start the morning with &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/good-test-better-code"&gt;Specification by example and Agile acceptance testing&lt;/a&gt; led by &lt;a href="http://gojko.net/"&gt;Gojko Adzic&lt;/a&gt;, it will be good to hear someone talk about testing as everything I’ve learnt has been picked up through screencasts and blogs.&lt;/p&gt;  &lt;p&gt;For the afternoon I’m uncertain whether to go for Gojko’s &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/web-testing-for-developers-with-application-models"&gt;FitNess.NET workshop&lt;/a&gt; or &lt;a href="http://serialseb.blogspot.com"&gt;Sebastien Lambla’s&lt;/a&gt; &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/openrasta-an-mvc-framework-with-strong-opinions"&gt;workshop on OpenRasta&lt;/a&gt;. I think how well I get on with Gojko’s style of presentation in the morning will be the deciding factor.&lt;/p&gt;  &lt;p&gt;In the evening I’m attempting to arrange &lt;a href="http://ukdotnet.ning.com/events/progressive-net-dinner"&gt;a meal&lt;/a&gt; with other people from the tutorials then probably go to a bar for a drink or two.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Tuesday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’m going to spend the whole day with &lt;a href="http://ayende.com/"&gt;Oren Eini&lt;/a&gt; learning about &lt;a href="https://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt;. Again this is something I’m using already but all I’ve learnt is taken from the internet. Learning from one of the developers of NHibernate is an opportunity that cannot be missed.&lt;/p&gt;  &lt;p&gt;In the evening Sebastien Lambla has arranged &lt;a href="http://ukdotnet.ning.com/events/london-altnetbeers-8"&gt;AltNetBeers&lt;/a&gt; where there will be an OpenConf style discussion. I’m looking forward to this nearly as much as the tutorials themselves.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Wednesday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Going to spend this day listening to &lt;a href="http://codebetter.com/blogs/david_laribee/"&gt;David Laribee's&lt;/a&gt; thoughts on project management and teamwork. I’m hoping to come away from this with inspiration on how I can help improve my team’s practices.&lt;/p&gt;  &lt;p&gt;Finishing it all off Skills Matter have arranged a trip to a pub for a drink or two. I’ll be spending about an hour there before catching the train back to Nottingham.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Thursday and Friday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’m planning on blogging about the things I’ve learnt over the previous 3 days. So look forward to a raft of blog posts.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I might get chance to knock together a blog post, but I’ll be tweeting whenever I get half a second spare so &lt;a href="http://twitter.com/gshutler"&gt;follow me&lt;/a&gt; if you’re interested in what’s going on.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3661595485405296346?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=whimeULDRu8:QG_Kn_nBllQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=whimeULDRu8:QG_Kn_nBllQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/whimeULDRu8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3661595485405296346/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3661595485405296346" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3661595485405296346?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3661595485405296346?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/whimeULDRu8/progressive-net-tutorials.html" title="Progressive .NET Tutorials" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/progressive-net-tutorials.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCR3o_fyp7ImA9WxJSGEo.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4384397612515431936</id><published>2009-05-09T14:57:00.001+01:00</published><updated>2009-05-09T14:57:46.447+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-09T14:57:46.447+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Extension methods" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><title>RhinoMocks IQueryable&lt;T&gt; helper</title><content type="html">&lt;p&gt;After reading &lt;a href="http://www.codebucket.org/archive/2009/05/07/using-nhibernate-to-test-your-query-logic-without-touching-the.aspx" target="_blank"&gt;Lee Brandt's post&lt;/a&gt; about how my answer to &lt;a href="http://stackoverflow.com/questions/448405/nhibernate-testing-mocking-isession" target="_blank"&gt;his question on Stack Overflow&lt;/a&gt; helped with testing the logic of his queries I realised that people might find one of my test helper extension methods useful.&lt;/p&gt;  &lt;p&gt;I found that in my tests I had to mock out the Query&amp;lt;T&amp;gt; function quite a lot which would look something like this:&lt;/p&gt;  &lt;div style="font-weight: bold; font-size: 10pt; background: #272727; padding-bottom: 0.6em; color: white; line-height: 1.2em; padding-top: 0.6em; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; EstablishContext()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; projects = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt;[]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;AAAAAAA&amp;quot;&lt;/span&gt;).Create(),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;CCCCCCC&amp;quot;&lt;/span&gt;).Create(),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;BBBBBBB&amp;quot;&lt;/span&gt;).Create()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="color: #6897bb"&gt;IUnitOfWork&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;()&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Stub(x =&amp;gt; x.Query&amp;lt;&lt;span style="color: #ffc66d"&gt;Project&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;())&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Return(projects.AsQueryable());&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This was adding quite a lot of noise to my tests. I like to keep my tests as clean as possible to make them easier to scan when you need to review and understand them. Because of this I wanted to simplify the stubbing so there was as little code as possible. &lt;/p&gt;  &lt;p&gt;This was made possible by this simple extension method:&lt;/p&gt;  &lt;div style="font-weight: bold; font-size: 10pt; background: #272727; padding-bottom: 0.6em; color: white; line-height: 1.2em; padding-top: 0.6em; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IMethodOptions&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IQueryable&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEntity&amp;gt;&amp;gt; ReturnQueryable&amp;lt;TEntity&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span style="color: #cc7832"&gt;this&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IMethodOptions&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IQueryable&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEntity&amp;gt;&amp;gt; options, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;params&lt;/span&gt; TEntity[] items)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; options.Return(items.AsQueryable());&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The magic sauce in this is the items parameter. I’ve used the params modifier so that I can provide any number of TEntity objects for the IQueryable function to return.&lt;/p&gt;  &lt;p&gt;This tidies the above setup code down to this:&lt;/p&gt;  &lt;div style="font-weight: bold; font-size: 10pt; background: #272727; padding-bottom: 0.6em; color: white; line-height: 1.2em; padding-top: 0.6em; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; EstablishContext()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="color: #6897bb"&gt;IUnitOfWork&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;()&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Stub(x =&amp;gt; x.Query&amp;lt;&lt;span style="color: #ffc66d"&gt;Project&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;())&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ReturnQueryable(&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;AAAAAAA&amp;quot;&lt;/span&gt;).Create(), &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;CCCCCCC&amp;quot;&lt;/span&gt;).Create(),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;BBBBBBB&amp;quot;&lt;/span&gt;).Create()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; );&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I find this much cleaner and easier to read, hope this helps someone out.&lt;/p&gt;  &lt;p&gt;Happy testing!&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html"&gt;Test aided development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/05/difference-between-areequal-and-aresame.html"&gt;Difference between AreEqual and AreSame&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2008/01/more-fluent-assertions-using-extension.html"&gt;More fluent assertions using extension methods&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4384397612515431936?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bVxQHCU7HUw:CZEhi3vgnpE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bVxQHCU7HUw:CZEhi3vgnpE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/bVxQHCU7HUw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/4384397612515431936/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=4384397612515431936" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4384397612515431936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4384397612515431936?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/bVxQHCU7HUw/rhinomocks-iqueryable-helper.html" title="RhinoMocks IQueryable&amp;lt;T&amp;gt; helper" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/rhinomocks-iqueryable-helper.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcFRH46eyp7ImA9WxJSF0U.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-6926690411661343781</id><published>2009-05-08T13:17:00.001+01:00</published><updated>2009-05-08T13:33:35.013+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-08T13:33:35.013+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>A new name for ALT.NET</title><content type="html">&lt;p&gt;I will be attending &lt;a href="http://progressive-dotnet.com/"&gt;Progressive .NET Tutorials&lt;/a&gt; next week and it got me thinking this morning.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Wouldn’t Progressive .NET be a much more &lt;strong&gt;positive&lt;/strong&gt; and &lt;strong&gt;inclusionary&lt;/strong&gt; name?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I’ve always felt the alternative part of ALT.NET to be quite elitist, exuding the feeling of “we’re different to you and that makes us better”.&lt;/p&gt;  &lt;p&gt;Lets look at &lt;a href="http://en.wiktionary.org/wiki/alternative"&gt;the dictionary definition of alternative&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;ol&gt;     &lt;li&gt;A situation which allows a mutually exclusive choice between two or more possibilities. &lt;/li&gt;      &lt;li&gt;A choice between two or more mutually exclusive possibilities. &lt;/li&gt;      &lt;li&gt;One of several mutually exclusive things which can be chosen. &lt;/li&gt;   &lt;/ol&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s all about choosing between different things and can give the impression of “it’s our way or the wrong way”.&lt;/p&gt;  &lt;p&gt;Progressive .NET (could be similarly shortened to PROG.NET) could soften the message of the ALT.NET movement whilst having the same meaning.&lt;/p&gt;  &lt;p&gt;For contrast, lets look at &lt;a href="http://en.wiktionary.org/wiki/progressive"&gt;the dictionary definition of progressive&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;ol&gt;     &lt;li&gt;Favouring or promoting progress; advanced. &lt;/li&gt;      &lt;li&gt;Gradually advancing in extent; increasing. &lt;/li&gt;      &lt;li&gt;Promoting or favouring progress towards improved conditions or new policies, ideas or methods: &lt;dl&gt;&lt;dd&gt;&lt;i&gt;a progressive politician.&lt;/i&gt;&lt;/dd&gt;&lt;dd&gt;&lt;i&gt;progressive business leadership.&lt;/i&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/blockquote&gt;  &lt;p&gt;Isn’t progression of the craft of software engineering what ALT.NET is all about?&lt;/p&gt;  &lt;p&gt;To be a part of ALT.NET I get the impression that you have to have mastered IoC, xDD, etc. before you can become a member. PROG.NET gives an altogether softer face, whilst still having the same ideals:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Want to improve your software? So do we, come join in.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Isn’t a message like that going to help ALT.NET &lt;a href="http://en.wikipedia.org/wiki/Technology_adoption_lifecycle"&gt;cross the chasm&lt;/a&gt;? Then again, some will say &lt;a href="http://smallbusiness.yahoo.com/r-article-a-113631-m-6-sc-45-whats_in_a_name_everything-i"&gt;what's in a name&lt;/a&gt;?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-6926690411661343781?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Vzf_VoapebM:IpLX03b_fZc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Vzf_VoapebM:IpLX03b_fZc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Vzf_VoapebM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/6926690411661343781/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=6926690411661343781" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/6926690411661343781?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/6926690411661343781?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Vzf_VoapebM/new-name-for-altnet.html" title="A new name for ALT.NET" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/new-name-for-altnet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMGQHY5fyp7ImA9WxJSFkw.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3492644928635849620</id><published>2009-05-06T15:00:00.001+01:00</published><updated>2009-05-06T15:00:21.827+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-06T15:00:21.827+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><title>Difference between AreEqual and AreSame</title><content type="html">&lt;p&gt;This is a question I’ve been asked at work before and the answer is quite important as it can lead to tests mysteriously failing.&lt;/p&gt;  &lt;p&gt;The difference between the two assertions are quite simple. Assert.AreSame checks that they are the exact same object, memory reference and all (in the case of .NET using &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.referenceequals.aspx" target="_blank"&gt;ReferenceEquals&lt;/a&gt;). Assert.AreEqual checks that objectOne.Equals(objectTwo) will return true.&lt;/p&gt;  &lt;p&gt;Here’s a simple example of how they will work with a sensible implementation of Equals.&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;\red128\green128\blue128;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b Example}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b private}\cf3 {\b  }\cf1 {\b int}\cf3 {\b  variable;}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  Example(}\cf1 {\b int}\cf3 {\b  variable)}\par ??{\b     \{}\par ??{\b         }\cf1 {\b this}\cf3 .variable = variable;\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b override}\cf3 {\b  }\cf1 {\b bool}\cf3 {\b  Equals(}\cf1 {\b object}\cf3 {\b  obj)}\par ??{\b     \{}\par ??{\b         }\cf1 {\b if}\cf3 {\b  (obj }\cf1 {\b is}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b )}\par ??{\b             }\cf1 {\b return}\cf3 {\b  Equals(obj }\cf1 {\b as}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b );}\par ??\par ??{\b         }\cf1 {\b return}\cf3 {\b  }\cf1 {\b base}\cf3 .Equals(obj);\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b private}\cf3 {\b  }\cf1 {\b bool}\cf3 {\b  Equals(}\cf4 {\b Example}\cf3 {\b  obj)}\par ??{\b     \{}\par ??{\b         }\cf1 {\b return}\cf3 {\b  variable == obj.variable;}\par ??{\b     \}}\par ??{\b \}}\par ??\par ??{\b [}\cf4 {\b TestFixture}\cf3 {\b ]}\par ??\cf1 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b Test}\par ??\cf3 {\b \{}\par ??{\b     [}\cf4 {\b Test}\cf3 {\b ]}\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  ExampleTest()}\par ??{\b     \{}\par ??{\b         }\cf1 {\b var}\cf3 {\b  one = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b (}\cf5 {\b 1}\cf3 {\b );}\par ??{\b         }\cf1 {\b var}\cf3 {\b  two = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b (}\cf5 {\b 1}\cf3 {\b );}\par ??{\b         }\cf1 {\b var}\cf3 {\b  three = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b (}\cf5 {\b 2}\cf3 {\b );}\par ??{\b         }\cf1 {\b var}\cf3 {\b  four = one;}\par ??\par ??{\b         }\cf4 {\b Assert}\cf3 .AreEqual(one, two);   \cf6 {\b // true}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreSame(one, two);    \cf6 {\b // false}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreEqual(two, three); \cf6 {\b // false}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreSame(two, three);  \cf6 {\b // false}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreEqual(one, four);  \cf6 {\b // true}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreSame(one, four);   \cf6 {\b // true}\par ??\cf3 {\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.6em; line-height: 1.2em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.6em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832"&gt;int&lt;/span&gt; variable;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; Example(&lt;span style="color: #cc7832"&gt;int&lt;/span&gt; variable)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.variable = variable;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832"&gt;bool&lt;/span&gt; Equals(&lt;span style="color: #cc7832"&gt;object&lt;/span&gt; obj)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;if&lt;/span&gt; (obj &lt;span style="color: #cc7832"&gt;is&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; Equals(obj &lt;span style="color: #cc7832"&gt;as&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #cc7832"&gt;base&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Equals(obj);&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832"&gt;bool&lt;/span&gt; Equals(&lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt; obj)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; variable == obj.variable;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt; [&lt;span style="color: #ffc66d"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Test&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; ExampleTest()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; one = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;(&lt;span style="color: #6897bb"&gt;1&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; two = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;(&lt;span style="color: #6897bb"&gt;1&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; three = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;(&lt;span style="color: #6897bb"&gt;2&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; four = one;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 34&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 35&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreEqual(one, two);&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// true&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 36&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreSame(one, two);&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// false&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 37&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreEqual(two, three); &lt;/span&gt;&lt;span style="color: gray"&gt;// false&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 38&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreSame(two, three);&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// false&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreEqual(one, four);&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// true&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreSame(one, four);&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// true&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;So long as you have a sensible Equals method that compares the values of the two objects you can follow these rules:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;If two objects are the same, they will be equal &lt;/li&gt;    &lt;li&gt;If two objects are equal, they may not be the same &lt;/li&gt;    &lt;li&gt;If two objects are not equal, they will not be the same &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So now you’ll know the answer next time someone asks what the difference between Assert.AreEqual and Assert.AreSame is.&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2008/01/more-fluent-assertions-using-extension.html"&gt;More fluent assertions using extension methods&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html"&gt;Test aided development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/05/beauty-of-rspec.html"&gt;Beauty of RSpec&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3492644928635849620?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Kg3Z0zV15q4:pK2SnLazEbQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Kg3Z0zV15q4:pK2SnLazEbQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Kg3Z0zV15q4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3492644928635849620/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3492644928635849620" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3492644928635849620?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3492644928635849620?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Kg3Z0zV15q4/difference-between-areequal-and-aresame.html" title="Difference between AreEqual and AreSame" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/difference-between-areequal-and-aresame.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4EQ3g_cSp7ImA9WxJSFUw.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-1332281920883703545</id><published>2009-05-05T10:13:00.001+01:00</published><updated>2009-05-05T10:15:02.649+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-05T10:15:02.649+01:00</app:edited><title>Feedburner RSS feed</title><content type="html">&lt;p&gt;I've become obsessed with statistics for this blog, no matter how small they are. To this end I've transferred my RSS feed over to Feedburner.&lt;/p&gt;&lt;p&gt;Anyone already subscribed shouldn't have to do anything as it should redirect automatically. However, you could resubscribe to be on the safe side.&lt;/p&gt;&lt;p&gt;&lt;a href="http://feeds2.feedburner.com/RobustSoftware" rel="alternate" type="application/rss+xml"&gt;&lt;img alt="" style="vertical-align:middle;border:0" src="http://www.feedburner.com/fb/images/pub/feed-icon32x32.png"/&gt;&lt;/a&gt;&amp;nbsp;&lt;a href="http://feeds2.feedburner.com/RobustSoftware" rel="alternate" type="application/rss+xml"&gt;Subscribe to feed&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-1332281920883703545?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=zN6J6x5Uh2g:EjOUCEFzzGs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=zN6J6x5Uh2g:EjOUCEFzzGs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=zN6J6x5Uh2g:EjOUCEFzzGs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=zN6J6x5Uh2g:EjOUCEFzzGs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=zN6J6x5Uh2g:EjOUCEFzzGs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=zN6J6x5Uh2g:EjOUCEFzzGs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=zN6J6x5Uh2g:EjOUCEFzzGs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/zN6J6x5Uh2g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/1332281920883703545/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=1332281920883703545" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1332281920883703545?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1332281920883703545?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/zN6J6x5Uh2g/feedburner-rss-feed.html" title="Feedburner RSS feed" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/feedburner-rss-feed.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUARn06cSp7ImA9WxJSFE4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-872856461699724820</id><published>2009-05-04T11:25:00.000+01:00</published><updated>2009-05-04T11:34:07.319+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-04T11:34:07.319+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="RSpec" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><title>Beauty of RSpec</title><content type="html">&lt;p&gt;I've only been using &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; in anger for a short period of time but I'm in love with it already. It's support for &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development"&gt;BDD&lt;/a&gt; is fantastic. I'm now looking forward to the proper release of &lt;a href="http://www.ironruby.net/"&gt;IronRuby&lt;/a&gt; even more than I was before.&lt;/p&gt;&lt;p&gt;I've only written a single class so far, but I'm delighted with the way the tests look so I thought I'd share them:&lt;/p&gt;&lt;div class="CodeRay"&gt;&lt;br /&gt;  &lt;div class="code" style="margin-left: 1em; border: solid 1px #ddd; line-height: 1em;"&gt;&lt;pre style="margin: 1em;"&gt;require &lt;span style="color:#036;font-weight:bold"&gt;File&lt;/span&gt;.expand_path(&lt;span style="color:#036;font-weight:bold"&gt;File&lt;/span&gt;.dirname(&lt;span style="color:#038;font-weight:bold"&gt;__FILE__&lt;/span&gt;) + &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;/../spec_helper&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;describe &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;setting a person's password&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  given &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#33B"&gt;@person&lt;/span&gt; = &lt;span style="color:#036;font-weight:bold"&gt;Person&lt;/span&gt;.new    &lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  because &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#33B"&gt;@person&lt;/span&gt;.set_password &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;testing&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt; &lt;br /&gt;  &lt;br /&gt;  it &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;sets their password salt&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#33B"&gt;@person&lt;/span&gt;.password_salt.should_not be_nil&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  it &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;sets their password hash&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#33B"&gt;@person&lt;/span&gt;.password_hash.should_not be_nil&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;    &lt;br /&gt;  &lt;br /&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;context &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;when someone has been saved&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;  &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  given &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#33B"&gt;@person&lt;/span&gt; = &lt;span style="color:#036;font-weight:bold"&gt;Person&lt;/span&gt;.new(&lt;span style="color:#A60"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;tester&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color:#33B"&gt;@person&lt;/span&gt;.set_password &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;testing&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#33B"&gt;@person&lt;/span&gt;.save&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  describe &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;providing their credentials&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;    because &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:#33B"&gt;@retrieved&lt;/span&gt; = &lt;span style="color:#036;font-weight:bold"&gt;Person&lt;/span&gt;.with_credentials(&lt;span style="color:#A60"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;tester&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#A60"&gt;:password&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;testing&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    it &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;retrieves the expected person&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:#33B"&gt;@retrieved&lt;/span&gt;.should == &lt;span style="color:#33B"&gt;@person&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;  &lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  describe &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;providing the wrong password&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    it_raises &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;an error informing the password is incorrect&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Incorrect password&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:#036;font-weight:bold"&gt;Person&lt;/span&gt;.with_credentials(&lt;span style="color:#A60"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;tester&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#A60"&gt;:password&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;wrong&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;describe &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;providing credentials for someone who does not exist&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  it_raises &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;an error informing the name is unknown&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Unknown name&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#036;font-weight:bold"&gt;Person&lt;/span&gt;.with_credentials(&lt;span style="color:#A60"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;tester&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#A60"&gt;:password&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;unsaved&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The output when you run the tests looks like:&lt;/p&gt;&lt;div style="margin-left: 1em; border: solid 1px #ddd; line-height: 1em;"&gt;&lt;pre style="margin: 1em;"&gt;~$ rake spec:doc&lt;br /&gt;(in /home/garry/code/rails/tinytweet)&lt;br /&gt;&lt;br /&gt;setting a person's password&lt;br /&gt;- sets their password salt&lt;br /&gt;- sets their password hash&lt;br /&gt;&lt;br /&gt;when someone has been saved providing their credentials&lt;br /&gt;- retrieves the expected person&lt;br /&gt;&lt;br /&gt;when someone has been saved providing the wrong password&lt;br /&gt;- raises an error informing the password is incorrect&lt;br /&gt;&lt;br /&gt;providing credentials for someone who does not exist&lt;br /&gt;- raises an error informing the name is unknown&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For those of you familiar with RSpec, you may notice that I'm not using the standard syntax. "given" and "because" are just aliases for "before". I've done this because I like the given/when/then style of tests but as "when" is a Ruby keyword and "it" helps you name the assertions properly for the docs it has become given/because/it.&lt;/p&gt;&lt;p&gt;I've also added an extra method "it_raises" as I found the way of testing that an error is raised rather clunky so I hid the nuts and bolts of it within my spec_helper.rb:&lt;/p&gt;&lt;div class="CodeRay"&gt;&lt;div class="code" style="margin-left: 1em; border: solid 1px #ddd; line-height: 1em;"&gt;&lt;pre style="margin: 1em;"&gt;&lt;span style="color:#080;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#06B;font-weight:bold"&gt;it_raises&lt;/span&gt;(description, error_message)&lt;br /&gt;  it &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;raises &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + description &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;br /&gt;    lambda { &lt;span style="color:#080;font-weight:bold"&gt;yield&lt;/span&gt; }.should raise_error error_message&lt;br /&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;No doubt I'll have more to share as my journey with Rails and RSpec continues.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-872856461699724820?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=mB6c9tH08TQ:uKkWRxAdkPw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=mB6c9tH08TQ:uKkWRxAdkPw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=mB6c9tH08TQ:uKkWRxAdkPw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=mB6c9tH08TQ:uKkWRxAdkPw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=mB6c9tH08TQ:uKkWRxAdkPw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=mB6c9tH08TQ:uKkWRxAdkPw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=mB6c9tH08TQ:uKkWRxAdkPw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/mB6c9tH08TQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/872856461699724820/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=872856461699724820" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/872856461699724820?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/872856461699724820?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/mB6c9tH08TQ/beauty-of-rspec.html" title="Beauty of RSpec" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/beauty-of-rspec.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YGQns-fCp7ImA9WxJSFE8.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-7469053744244114133</id><published>2009-05-04T10:21:00.000+01:00</published><updated>2009-05-04T10:25:23.554+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-04T10:25:23.554+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="RSpec" /><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Installing Ruby, Rails and RSpec on Ubuntu</title><content type="html">&lt;p&gt;So I had quite a nightmare with this one, but once I'd found the problem the installation was annoyingly simple. The crux of the problem is that Ubuntu's package manager will install old versions of both &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt; and &lt;a href="http://rubygems.org/"&gt;RubyGems&lt;/a&gt; that are not compatible with the latest version of &lt;a href="http://rspec.info/documentation/"&gt;RSpec&lt;/a&gt; and &lt;a href="http://rspec.info/rails/"&gt;RSpec-Rails&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So, here's the steps I went through to go from nothing at all installed to a fully functioning Rails app with RSpec-Rails support:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Use the package manager to install Ruby 1.8.7&lt;/li&gt;&lt;li&gt;Manually download&amp;nbsp; the latest version of RubyGems &lt;a href="http://rubyforge.org/frs/?group_id=126"&gt;from here&lt;/a&gt; (do NOT use the package manager for this)&lt;/li&gt;&lt;li&gt;Extract and follow the instructions to install RubyGems&lt;/li&gt;&lt;li&gt;Use RubyGems to install everything else:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;[sudo] gem1.8 install rake&lt;/li&gt;&lt;li&gt;[sudo] gem1.8 install rails&lt;/li&gt;&lt;li&gt;[sudo] gem1.8 install rspec-rails&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The last command will pull in the main RSpec gem as it is one of its dependencies.&lt;/p&gt;&lt;p&gt;Once you have created your rails app go to its directory run the command "script/generate rspec" then you're ready to rock and roll.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-7469053744244114133?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tC5_tenZDSM:5qW9_4POnLg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=tC5_tenZDSM:5qW9_4POnLg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tC5_tenZDSM:5qW9_4POnLg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tC5_tenZDSM:5qW9_4POnLg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=tC5_tenZDSM:5qW9_4POnLg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tC5_tenZDSM:5qW9_4POnLg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tC5_tenZDSM:5qW9_4POnLg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/tC5_tenZDSM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/7469053744244114133/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=7469053744244114133" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7469053744244114133?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7469053744244114133?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/tC5_tenZDSM/installing-ruby-rails-and-rspec-on.html" title="Installing Ruby, Rails and RSpec on Ubuntu" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/installing-ruby-rails-and-rspec-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMERHwzcSp7ImA9WxJTFUs.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-7653549651534420192</id><published>2009-04-24T10:44:00.001+01:00</published><updated>2009-04-24T10:46:45.289+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T10:46:45.289+01:00</app:edited><title>New comments from Intense Debate</title><content type="html">&lt;p&gt;I’ve been disappointed by the comments provided by blogger so I thought I’d look at applications that can be used instead.&lt;/p&gt;  &lt;p&gt;I know that &lt;a href="http://blog.wekeroad.com/" target="_blank"&gt;Rob Conery&lt;/a&gt; had a similar problem at some point so I thought I’d try out what he is using: &lt;a href="http://intensedebate.com/" target="_blank"&gt;Intense Debate&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I’ll see how it goes.&lt;/p&gt;  &lt;p&gt;What I can say about it is that the install process was &lt;strong&gt;really &lt;/strong&gt;easy. They really made it as easy as possible for you to use their commenting system.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-7653549651534420192?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=m3yfGRkqRFs:SPZJgiHfgx8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=m3yfGRkqRFs:SPZJgiHfgx8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=m3yfGRkqRFs:SPZJgiHfgx8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=m3yfGRkqRFs:SPZJgiHfgx8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=m3yfGRkqRFs:SPZJgiHfgx8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=m3yfGRkqRFs:SPZJgiHfgx8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=m3yfGRkqRFs:SPZJgiHfgx8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/m3yfGRkqRFs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/7653549651534420192/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=7653549651534420192" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7653549651534420192?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7653549651534420192?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/m3yfGRkqRFs/new-comments-from-intense-debate.html" title="New comments from Intense Debate" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/04/new-comments-from-intense-debate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4GQn48eSp7ImA9WxJTFUg.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-2588567358653017241</id><published>2009-04-24T08:05:00.001+01:00</published><updated>2009-04-24T08:08:43.071+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T08:08:43.071+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Replication" /><title>SQL Server 2005 replication errors table</title><content type="html">&lt;p&gt;Just a quick one so I have this as a reference as it takes me a while to find it each time I forget.&lt;/p&gt;  &lt;p&gt;The SQL statement to get the errors from replication as the ones the monitor gives you can be very vague is:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; msdb.dbo.sysreplicationalerts&lt;/pre&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;Note that it is only a status type message unless error_id is not zero.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-2588567358653017241?l=blog.robustsoftware.co.uk'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=HWw7LT1CPcM:mRYiJdLtmMc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=HWw7LT1CPcM:mRYiJdLtmMc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=HWw7LT1CPcM:mRYiJdLtmMc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=HWw7LT1CPcM:mRYiJdLtmMc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=HWw7LT1CPcM:mRYiJdLtmMc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=HWw7LT1CPcM:mRYiJdLtmMc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=HWw7LT1CPcM:mRYiJdLtmMc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/HWw7LT1CPcM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/2588567358653017241/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=2588567358653017241" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/2588567358653017241?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/2588567358653017241?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/HWw7LT1CPcM/sql-server-2005-replication-errors.html" title="SQL Server 2005 replication errors table" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/04/sql-server-2005-replication-errors.html</feedburner:origLink></entry></feed>
