<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">

<channel>
	<title>Developing...</title>
	
	<link>http://timescott.wordpress.com</link>
	<description>...me as a developer and hopefully some software along the way</description>
	<lastBuildDate>Mon, 05 Oct 2009 19:24:49 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain="timescott.wordpress.com" port="80" path="/?rsscloud=notify" registerProcedure="" protocol="http-post" />
<image>
		<url>http://www.gravatar.com/blavatar/5574249c81461caa91eeae48ff2b0ba0?s=96&amp;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Developing...</title>
		<link>http://timescott.wordpress.com</link>
	</image>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/timescott" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Functional Testing with Twist</title>
		<link>http://timescott.wordpress.com/2009/10/03/functional_testing_with_twist/</link>
		<comments>http://timescott.wordpress.com/2009/10/03/functional_testing_with_twist/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 16:30:26 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[FitNesse]]></category>
		<category><![CDATA[Functional Testing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Twist]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/?p=116</guid>
		<description><![CDATA[Twist is an automated functional testing framework from ThoughtWorks Studios. I am used to using FitNesse so I am interested in seeing how the two products compare.
Writing your first real FitNesse test can be tricky business, which fixture should I use, where does my wiki mark up go, how is my wiki markup different depending [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=116&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Twist is an automated functional testing framework from <a title="http://studios.thoughtworks.com" href="http://studios.thoughtworks.com" target="_blank">ThoughtWorks Studios</a>. I am used to using <a title="http://fitnesse.org/" href="http://fitnesse.org/" target="_blank">FitNesse</a> so I am interested in seeing how the two products compare.</p>
<p>Writing your first real FitNesse test can be tricky business, which fixture should I use, where does my wiki mark up go, how is my wiki markup different depending on which fixture type I choose etc etc. Using Twist I found that it took only about 10 minutes to write and execute my first fixture, scenario in Twist language and this is what was involved :</p>
<ul>
<li>Create a new project</li>
</ul>
<p><img class="aligncenter size-full wp-image-118" title="CreateNewTwistProject" src="http://timescott.files.wordpress.com/2009/09/createnewtwistproject.png?w=497&#038;h=500" alt="CreateNewTwistProject" width="497" height="500" /></p>
<ul>
<li>Create a new scenario and call it something like &#8216;When searching for Twist on Google&#8217;</li>
<li>Using the intellisense sortcut in elclipse, ctrl+space, Twist gives you the option of adding a new &#8216;Business Scenario&#8217; . Select this option and name the scenario &#8216;Should display the link to the twist home page&#8217;.</li>
</ul>
<p>To define the steps that Twist should carry out you write a bulleted list of actions, here is my example:</p>
<p><img class="aligncenter size-full wp-image-122" title="NewWorkflow" src="http://timescott.files.wordpress.com/2009/10/newworkflow1.png?w=497&#038;h=243" alt="NewWorkflow" width="497" height="243" /></p>
<p>At this point you can execute the scenario, click on the execute button in the top right of the screen, the test will run but will fail. The error message is &#8220;java.lang.Exception: Context &#8220;New Context&#8221; is not implemented&#8221;, cryptically, this is telling me that I have to go and implement the java that will execute this workflow.</p>
<p>The context contains the setup and tear down code for the test, to create this click on the at the top.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">import com.thoughtworks.twist.driver.selenium.TwistSelenium;

public class NewContext {

	private TwistSelenium selenium;

	public NewContext(TwistSelenium selenium) {
		this.selenium = selenium;
	}

	public void setUp() throws Exception {
		selenium.open("http://www.google.co.uk");
	}

	public void tearDown() throws Exception {
		selenium.close();
	}
}</pre>
</div>
<p>Run the scenario again and you will get the following exception &#8216;java.lang.Exception: Workflow step &#8220;Enter text &#8220;Twist&#8221;" is not implemented&#8217;. This is telling you to create a method called &#8216;enterText&#8217;. To implement this you can click on the workflow item and use ctrl+space again this will give you an option to generate a stub class with the correct name. You can create the method &#8216;enterText&#8217; by clicking on the &#8216;Enter text &#8220;Twist&#8221;&#8216; workflow item and using ctrl+space this will again give you an option of creating the method stub with the correct name, implement the method and re-run the test.</p>
<p>Re-running the test will give you another exception, not surprisingly, telling me that the clickOn method is not declared, so I implement that and the last method, assertThatExistsOnThePage, and run the test one more time. Hoooray, it passes, I can see IE start up and selenium running through my scenario. Cool stuff.</p>
<p>Here is the code I finished up with:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">// JUnit Assert framework can be used for verification

import com.thoughtworks.twist.driver.selenium.TwistSelenium;

public class ShouldFindThoughtWorksInTheSearchResults {

	private TwistSelenium selenium;

	public ShouldFindThoughtWorksInTheSearchResults(TwistSelenium selenium) {
		this.selenium = selenium;
	}

	public void enterText(String text) throws Exception {
		selenium.type("q", text);
	}

	public void clickOn(String identifier) throws Exception {
		selenium.click(identifier);
	}

	public void assertThatExistsOnThePage(String text) throws Exception {
		assertThatExistsOnThePage(text);
	}
}</pre>
</div>
<p>Aside: Another nice feature of Twist, is it has tight integration with a unit testing framework, jUnit, which I can leverage to implement my assertions, FitNesse does not give you this tight integration.</p>
<p>Another aside: I am sure you have worked this out but the correlation between the steps in the business workflow and the methods that are created in java is as follows. Each step in the business workflow represents a method call, the methods are named by concatenating the words that are not in quotes and applying camelCasing, the words that are in quotes are the parameters that the method takes and are passed to the method in the order they appear. This is quite similar to the Do fixture in FitNesse.</p>
<p>Twist has an integrated environment for writing your tests, it is built ontop of elclipse, which is something that FitNesse lacks, it also doesn&#8217;t require you to learn any wiki markup to specify your scenarios. For me this is more of a benifit, whilst you are getting over the initial learning curve, as you become more proficient this is likley to be less important.</p>
<p>I use FitNesse for testing subsystems, things like individual services and for end-to-end testing, obviously for testing the whole system. The immediate disadvantage with Twist is that I can&#8217;t use it for subsystem testing. Twist has been designed to sit on-top of tools like selenium and Frankenstein which drive the UI. Additionally I predominatly work in a .Net environment, FitNesse provides a .Net adaptor to allow me to get into the code and configure and host my services, Twist doesn&#8217;t provide that level of support for anything that is not written in Java. An obvious downside to Twist vs FitNesse is that it is a paid for product.</p>
<p>I have used Twist to add tests here to add tests to an existing system, I see no reason why you couldn&#8217;t use this to specify your system as well before it has been created.</p>
<p>After only a brief encounter with Twist I&#8217;m not sure if it is as flexible or mature as FitNesse but it looks like a nice product to use and I can definatly see that it has its place. I have definatly got some more questions regarding Twist so will be spending some more time figuring out what is possible with it. It would also seem to be lacking one key feature which is integration with Mingle, without this you are going to have to maintain 2 separate sets of requirements.</p>
<p>You can download a trial version of Twist from: <a href="http://studios.thoughtworks.com/agile-test-automation" target="_blank">ThoughtWorks Studios</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/116/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/116/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=116&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/xwpw-2eRpa4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2009/10/03/functional_testing_with_twist/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2009/09/createnewtwistproject.png" medium="image">
			<media:title type="html">CreateNewTwistProject</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2009/10/newworkflow1.png" medium="image">
			<media:title type="html">NewWorkflow</media:title>
		</media:content>
	</item>
		<item>
		<title>Uninstalling Picasa – Ubuntu</title>
		<link>http://timescott.wordpress.com/2009/05/29/uninstalling-picasa-ubuntu/</link>
		<comments>http://timescott.wordpress.com/2009/05/29/uninstalling-picasa-ubuntu/#comments</comments>
		<pubDate>Fri, 29 May 2009 20:48:22 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/2009/05/29/uninstalling-picasa-ubuntu/</guid>
		<description><![CDATA[It seems that there is no obvious way to uninstall Picasa on Ubuntu.
After some quick Googling I found a simple way to do it.
Just run:
sudo aptitude remove picasa
Done!
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=107&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>It seems that there is no obvious way to uninstall Picasa on Ubuntu.</p>
<p>After some quick Googling I found a simple way to do it.</p>
<p>Just run:<br />
sudo aptitude remove picasa</p>
<p>Done!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/107/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=107&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/iLIaN1Xjj7A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2009/05/29/uninstalling-picasa-ubuntu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>
	</item>
		<item>
		<title>Unlocking G1 for Vodafone UK</title>
		<link>http://timescott.wordpress.com/2009/01/06/unlocking-g1-for-vodafone-uk/</link>
		<comments>http://timescott.wordpress.com/2009/01/06/unlocking-g1-for-vodafone-uk/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 22:15:59 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[G1]]></category>
		<category><![CDATA[Unlock]]></category>
		<category><![CDATA[Vodafone]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/2009/01/06/unlocking-g1-for-vodafone-uk/</guid>
		<description><![CDATA[I was lucky enough to get a G1 for Christmas last year, as true for all new G1&#8217;s in the UK the phone was sim-locked to T-Mobile. This is a quick guide to how you can unlock the phone for use on Vodafone UK, you&#8217;ll be up and running in 5 minutes flat!
With the phone [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=88&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I was lucky enough to get a <a href="http://www.t-mobileg1.com/" target="_blank">G1</a> for Christmas last year, as true for all new G1&#8217;s in the UK the phone was sim-locked to T-Mobile. This is a quick guide to how you can unlock the phone for use on Vodafone UK, you&#8217;ll be up and running in 5 minutes flat!</p>
<p>With the phone my girlfriend had given me an ghost-sim to do the unlocking. The chip is a thin pcb with a single microchip in one corner. The ghost-sim is designed to live between the contacts on your sim card and the contacts on the phone. Although the ghost-sim is very thin the microchip is quite big. This means that to get a good fit you will need make a couple of small cuts on the sim card.</p>
<p><a href="http://timescott.files.wordpress.com/2009/01/unlock-chip.png"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://timescott.files.wordpress.com/2009/01/unlock-chip-thumb.png?w=236&#038;h=150" border="0" alt="unlock-chip" width="236" height="150" /> <img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://timescott.files.wordpress.com/2009/01/sim-cut-thumb.png?w=221&#038;h=150" border="0" alt="sim-cut" width="221" height="150" /></a></p>
<p><a href="http://timescott.files.wordpress.com/2009/01/sim-cutdone.png"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;padding-left:100px;" src="http://timescott.files.wordpress.com/2009/01/sim-cutdone-thumb.png?w=239&#038;h=149" border="0" alt="sim-cutdone" width="239" height="149" /></a></p>
<p>You have quite enough space at this end of the sim card before you get anywhere near the contacts on the back, so no need to worry about that! Once you have cut the sim card you can now slide it together with the ghost-sim into your G1, put the battery in and switch it on. The ghost-sim will unlock the phone from the minute the phone is switched on but by default the phone only knows about T-Mobile Access Point Names, so you&#8217;ll have to add some settings to get the phone working on Vodafone.</p>
<p>When the phone comes on you should see the &#8220;Login to your Google account screen&#8221;, press the phones&#8217; menu button, the &#8220;New APN&#8221; menu will popup. Select it and enter the following settings for Vodafone UK.</p>
<blockquote><p><strong>Name</strong>: Vodafone</p>
<p><strong>APN</strong>: wap.vodafone.co.uk</p>
<p><strong>Username</strong>: wap</p>
<p><strong>Password</strong>: wap</p>
<p>Leave the MMC and MNC settings with their default values (234 &amp; 15).</p></blockquote>
<p>All other settings should be left blank otherwise you will not be able to connect, this caught me out! Save the new APN by using the menu button again. You should now be able to get a 3G connection and login to your Google account. All services other than MMS (some extra settings are required for this) should be available to you. I have been using my G1 for a couple of weeks now without any problems.</p>
<p>This was written from memory so if I have missed a step let me know and I&#8217;ll update.</p>
<p>Cheers</p>
<p>Tim</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/88/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=88&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/gTcM_Zr_hKY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2009/01/06/unlocking-g1-for-vodafone-uk/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2009/01/unlock-chip-thumb.png" medium="image">
			<media:title type="html">unlock-chip</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2009/01/sim-cut-thumb.png" medium="image">
			<media:title type="html">sim-cut</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2009/01/sim-cutdone-thumb.png" medium="image">
			<media:title type="html">sim-cutdone</media:title>
		</media:content>
	</item>
		<item>
		<title>Running integration tests using Cassini and NUnit</title>
		<link>http://timescott.wordpress.com/2008/12/09/running-integration-tests-using-cassini/</link>
		<comments>http://timescott.wordpress.com/2008/12/09/running-integration-tests-using-cassini/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 20:31:12 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ASP.Net MVC]]></category>
		<category><![CDATA[Cassini]]></category>
		<category><![CDATA[Integration Tests]]></category>
		<category><![CDATA[NUnit]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/2008/12/09/running-integration-tests-using-cassini/</guid>
		<description><![CDATA[Recently, at work, I had the opportunity to do some work on a greenfield ASP.Net MVC application. Part of the development involved creating a suite of integration tests/specs. I had worked on projects where we had written integration tests before but they relied on having an installation of the system, this usually means configuring IIS, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=80&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Recently, at work, I had the opportunity to do some work on a greenfield ASP.Net MVC application. Part of the development involved creating a suite of integration tests/specs. I had worked on projects where we had written integration tests before but they relied on having an installation of the system, this usually means configuring IIS, around for the tests to run against. This has not always been available on the CI server. A better solution is to create an instance of a web server as part of the TestFixtureSetUp. Here&#8217;s how easy it is with <a title="Cassini download" href="http://www.asp.net/Downloads/archived/cassini/" target="_blank">Cassini</a>.</p>
<p>Create an abstract class that forms the base class for the integration tests.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> System.Configuration;
<span style="color:#0000ff;">using</span> Cassini;
<span style="color:#0000ff;">using</span> NUnit.Framework;

<span style="color:#0000ff;">namespace</span> TimEscott.Blog.WebApp.Tests.Integration
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">class</span> IntegrationTestBase
    {
        <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">readonly</span> IntegrationTestConfig config;
        <span style="color:#0000ff;">private</span> Server webServer;

        <span style="color:#0000ff;">protected</span> IntegrationTestBase()
        {
            config = (IntegrationTestConfig) ConfigurationManager.GetSection(<span style="color:#006080;">"IntegrationTest"</span>);

            <span style="color:#0000ff;">if</span>(config == <span style="color:#0000ff;">null</span>)
            {
                <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> IntegrationTestConfigurationException(<span style="color:#006080;">"Could not load configuration information to run the integration tests."</span>);
            }
        }

        [TestFixtureSetUp]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> TestFixtureSetup()
        {
            webServer = <span style="color:#0000ff;">new</span> Server(config.Port, config.VirtualPath, config.PhysialPath);
            webServer.Start();
        }

        [TestFixtureTearDown]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> TestFixtureTearDown()
        {
            <span style="color:#0000ff;">if</span>(webServer != <span style="color:#0000ff;">null</span>)
            {
                webServer.Stop();
            }
        }

        <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">string</span> BuildTestUrl(<span style="color:#0000ff;">string</span> path)
        {
            <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">string</span>.Format(<span style="color:#006080;">"http://localhost:{0}/{1}"</span>, config.Port, path);
        }
    }
}</pre>
</div>
<p>So now I can create an integration test, using WatiN:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;height:200px;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> NUnit.Framework;
<span style="color:#0000ff;">using</span> NUnit.Framework.SyntaxHelpers;
<span style="color:#0000ff;">using</span> WatiN.Core;

<span style="color:#0000ff;">namespace</span> TimEscott.Blog.WebApp.Tests.Integration.Home
{
    [TestFixture]
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> When_loading_the_home_page : IntegrationTestBase
    {
        [Test]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Should_contain_the_correct_title()
        {
            <span style="color:#0000ff;">using</span> (var ie = <span style="color:#0000ff;">new</span> IE())
            {
                ie.GoTo(BuildTestUrl(<span style="color:#006080;">"Home"</span>));

                Assert.That(ie.ContainsText(<span style="color:#006080;">"Welcome to ASP.NET MVC!"</span>), Is.True);
            }
        }

    }
}</pre>
</div>
<p>Here is the config class and the app.config for completeness:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> System.Configuration;

<span style="color:#0000ff;">namespace</span> TimEscott.Blog.WebApp.Tests.Integration
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> IntegrationTestConfig : ConfigurationSection
    {
        [ConfigurationProperty(<span style="color:#006080;">"Port"</span>, IsRequired = <span style="color:#0000ff;">true</span>)]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">int</span> Port
        {
            get { <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">int</span>.Parse(<span style="color:#0000ff;">this</span>[<span style="color:#006080;">"Port"</span>].ToString()); }
        }

        [ConfigurationProperty(<span style="color:#006080;">"VirtualPath"</span>, IsRequired = <span style="color:#0000ff;">true</span>)]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> VirtualPath
        {
            get { <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">this</span>[<span style="color:#006080;">"VirtualPath"</span>].ToString(); }
        }

        [ConfigurationProperty(<span style="color:#006080;">"PhysialPath"</span>, IsRequired = <span style="color:#0000ff;">true</span>)]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> PhysialPath
        {
            get { <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">this</span>[<span style="color:#006080;">"PhysialPath"</span>].ToString(); }
        }
    }
}</pre>
</div>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">&lt;?</span><span style="color:#800000;">xml</span> <span style="color:#ff0000;">version</span><span style="color:#0000ff;">="1.0"</span> <span style="color:#ff0000;">encoding</span><span style="color:#0000ff;">="utf-8"</span> ?<span style="color:#0000ff;">&gt;</span>
<span style="color:#0000ff;">&lt;</span><span style="color:#800000;">configuration</span><span style="color:#0000ff;">&gt;</span>
  <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">configSections</span><span style="color:#0000ff;">&gt;</span>
    <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">section</span> <span style="color:#ff0000;">name</span><span style="color:#0000ff;">="IntegrationTests"</span>
             <span style="color:#ff0000;">type</span><span style="color:#0000ff;">="TimEscott.Blog.WebApp.Tests.Integration.IntegrationTestConfig, TimEscott.Blog.WebApp.Tests.Integration"</span><span style="color:#0000ff;">/&gt;</span>
  <span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">configSections</span><span style="color:#0000ff;">&gt;</span>
  <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">IntegrationTests</span> <span style="color:#ff0000;">Port</span><span style="color:#0000ff;">="4015"</span>
                   <span style="color:#ff0000;">VirtualPath</span><span style="color:#0000ff;">="/"</span>
                   <span style="color:#ff0000;">PhysialPath</span><span style="color:#0000ff;">="C:\Projects\Blog\TimEscott.Blog.WebApp\"</span> <span style="color:#0000ff;">/&gt;</span>
<span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">configuration</span><span style="color:#0000ff;">&gt;</span></pre>
</div>
<p>This in conjunction with something like Ayende&#8217;s <a title="SqlCEDbHelper source" href="http://rhino-tools.svn.sf.net/svnroot/rhino-tools/trunk/rhino-commons/Rhino.Commons/Helpers/SqlCEDbHelper.cs" target="_blank">SqlCEDbHelper</a> as a mechanism to help create a test database, gives a very portable test suite which can run anywhere that .Net and Cassini are installed.</p>
<p><a href="http://www.hanselman.com/blog/NUnitUnitTestingOfASPNETPagesBaseClassesControlsAndOtherWidgetryUsingCassiniASPNETWebMatrixVisualStudioWebDeveloper.aspx" target="_blank">Scott Hanselman describes</a> one way to remove the pre-requisite we have here (having the Cassini dll installed in the GAC). But for the sake of having one dll installed on an internal server I am currently not too worried about having this dependency.</p>
<p>A nice addition might be to actually check that the port is free, if not find one that is?!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/80/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=80&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/MKfaiFWDVHY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2008/12/09/running-integration-tests-using-cassini/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>
	</item>
		<item>
		<title>Fluent Rhino Mocks</title>
		<link>http://timescott.wordpress.com/2008/10/30/fluent-rhino-mocks/</link>
		<comments>http://timescott.wordpress.com/2008/10/30/fluent-rhino-mocks/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 20:59:16 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[NUnit]]></category>
		<category><![CDATA[Rhino Mocks]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/2008/10/30/fluent-rhino-mocks/</guid>
		<description><![CDATA[I was recently introduced to the fluent interface that the Rhino Mocks library exposes. I wasn&#8217;t sure that it was as easy to read as the Record/Playback syntax I was use to using. I persisted with the &#8216;new&#8217; syntax to see if I could see any benefit of using the fluent interface.
I now find that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=76&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I was recently introduced to the fluent interface that the Rhino Mocks library exposes. I wasn&#8217;t sure that it was as easy to read as the Record/Playback syntax I was use to using. I persisted with the &#8216;new&#8217; syntax to see if I could see any benefit of using the fluent interface.</p>
<p>I now find that using the fluent interface helps on a number of fronts.</p>
<ul>
<li>Eliminates many potential mistakes buy using method chaining.</li>
<li>Helps me keep to one Expectation or Assert per test.</li>
<li>Makes my code more like an English sentence and therefore easier to read.</li>
<li>Means that my code is smaller.</li>
<li>Allows me to use ExpectingInSameOrder &#8211; although I haven&#8217;t found a really good use for this yet.</li>
</ul>
<p>I have to say I wasn&#8217;t instantly sold on the syntax but the more I used it the more I like it.</p>
<p>Here is a simple example of a refactored test using the fluent interface.</p>
<h3>Original</h3>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">[Test]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Should_leverage_the_repository_to_retrieve_all_games()
{
    <span style="color:#0000ff;">using</span> (mockery.Record())
    {
        Expect.Call(repository.Find(<span style="color:#0000ff;">null</span>)).Return(<span style="color:#0000ff;">new</span> List&lt;Game&gt;()).IgnoreArguments();
    }

    <span style="color:#0000ff;">using</span> (mockery.Playback())
    {
        service.GetGames();
    }
}</pre>
</div>
<h3>New</h3>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">[Test]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Should_leverage_the_repository_to_retrieve_all_games()
{
    With.Mocks(mockery)
        .Expecting(() =&gt; Expect.Call(repository.Find(<span style="color:#0000ff;">null</span>)).Return(<span style="color:#0000ff;">new</span> List&lt;Game&gt;()).IgnoreArguments())
        .Verify(() =&gt; service.GetGames());
}</pre>
</div>
<p>A whole 50% smaller!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/76/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=76&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/CTbKpXtmn2I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2008/10/30/fluent-rhino-mocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>
	</item>
		<item>
		<title>TDD with Monorail – Part 6</title>
		<link>http://timescott.wordpress.com/2008/08/06/tdd-with-monorail-part-6/</link>
		<comments>http://timescott.wordpress.com/2008/08/06/tdd-with-monorail-part-6/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 20:32:48 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Castle]]></category>
		<category><![CDATA[Mappers]]></category>
		<category><![CDATA[Repositories]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Unit Tests]]></category>
		<category><![CDATA[Windsor]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/?p=71</guid>
		<description><![CDATA[As promised the mapping and repository layers&#8230;
Not much of particular interest here really, but for the sake of completeness I will write about what I have done in these areas.
The Mappers
The mappers are mainly a supporting mechanism to allow me to send messages through the API interface rather than the domain objects themselves. A mapping [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=71&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>As promised the mapping and repository layers&#8230;</p>
<p>Not much of particular interest here really, but for the sake of completeness I will write about what I have done in these areas.</p>
<h3>The Mappers</h3>
<p>The mappers are mainly a supporting mechanism to allow me to send messages through the API interface rather than the domain objects themselves. A mapping classes simply takes an object of a specific type and returns an object of another type. The interface implemented by all my mappers also defines a method for doing this for a collection of the same types. Here is how I implemented a mapper for my SaveUserRequest message and User domain classes.</p>
<p><a href="http://timescott.files.wordpress.com/2008/08/mappers.png"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://timescott.files.wordpress.com/2008/08/mappers-thumb.png?w=415&#038;h=240" border="0" alt="mappers" width="415" height="240" /></a></p>
<p><strong>The test</strong></p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> NUnit.Framework;
<span style="color:#0000ff;">using</span> NUnit.Framework.SyntaxHelpers;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Mappers;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Specs.Builders.Domain;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Specs.Builders.Messages;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Specs.Unit.Mappers
{
    [TestFixture]
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> When_mapping_a_save_user_request_to_a_user : UnitTestBase
    {
        <span style="color:#0000ff;">private</span> IUserMapper mapper;

        [SetUp]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SetUp()
        {
            userBuilder = <span style="color:#0000ff;">new</span> UserBuilder();
            saveUserRequestBuilder = <span style="color:#0000ff;">new</span> SaveUserRequestBuilder();
            mapper = <span style="color:#0000ff;">new</span> UserMapper();
        }

        [Test]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Should_create_a_user()
        {
            var expectedUser = userBuilder.BuildVaildObject();

            var actualUser = mapper.MapFrom(saveUserRequestBuilder.BuildVaildObject());

            Assert.That(actualUser.Email, Is.EqualTo(expectedUser.Email));
            Assert.That(actualUser.FirstName, Is.EqualTo(expectedUser.FirstName));
            Assert.That(actualUser.Surname, Is.EqualTo(expectedUser.Surname));
            Assert.That(actualUser.Phone, Is.EqualTo(expectedUser.Phone));
        }
    }
}</pre>
</div>
<p><strong>The implementation</strong> &#8211; notice that I have not implemented the map collection method yet as I do not have a requirement for it.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> System.Collections.Generic;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Domain;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Messages.Users;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Core.Mappers
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> UserMapper : IUserMapper
    {
        <span style="color:#0000ff;">public</span> User MapFrom(ISaveUserRequest source)
        {
            <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> User()
                       {
                           Email = source.Email,
                           FirstName = source.FirstName,
                           Surname = source.Surname,
                           Phone = source.Phone
                       };
        }

        <span style="color:#0000ff;">public</span> IEnumerable&lt;User&gt; MapCollection(IEnumerator&lt;ISaveUserRequest&gt; sources)
        {
            <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> System.NotImplementedException();
        }
    }
}</pre>
</div>
<p>I am not really sure that there is much more to say about the mappers.</p>
<h3>The Repository layer</h3>
<p>This is where things are quite exciting for me. Coming from a world without ORM, now that I know about it I don&#8217;t know how I ever lived without it. I am using another part of the Castle stack here, ActiveRecord. To use ActiveRecord there is a couple of things I need to do to wire things up. Firstly I need to add the ActiveRecord config to the Windsor config files.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">&lt;</span><span style="color:#800000;">facility</span>
            <span style="color:#ff0000;">id</span><span style="color:#0000ff;">="activerecord"</span>
            <span style="color:#ff0000;">type</span><span style="color:#0000ff;">="Castle.Facilities.ActiveRecordIntegration.ActiveRecordFacility, Castle.Facilities.ActiveRecordIntegration"</span>
            <span style="color:#ff0000;">isDebug</span><span style="color:#0000ff;">="false"</span>
            <span style="color:#ff0000;">isWeb</span><span style="color:#0000ff;">="true"</span><span style="color:#0000ff;">&gt;</span>

      <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">assemblies</span><span style="color:#0000ff;">&gt;</span>
        <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">item</span><span style="color:#0000ff;">&gt;</span>TimEscott.GrassRoots.Core<span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">item</span><span style="color:#0000ff;">&gt;</span>
      <span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">assemblies</span><span style="color:#0000ff;">&gt;</span>

      <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">config</span><span style="color:#0000ff;">&gt;</span>
        <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">add</span> <span style="color:#ff0000;">key</span><span style="color:#0000ff;">="connection.driver_class"</span> <span style="color:#ff0000;">value</span><span style="color:#0000ff;">="NHibernate.Driver.SqlClientDriver"</span> <span style="color:#0000ff;">/&gt;</span>
        <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">add</span> <span style="color:#ff0000;">key</span><span style="color:#0000ff;">="dialect"</span> <span style="color:#ff0000;">value</span><span style="color:#0000ff;">="NHibernate.Dialect.MsSql2000Dialect"</span> <span style="color:#0000ff;">/&gt;</span>
        <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">add</span> <span style="color:#ff0000;">key</span><span style="color:#0000ff;">="connection.provider"</span> <span style="color:#ff0000;">value</span><span style="color:#0000ff;">="NHibernate.Connection.DriverConnectionProvider"</span> <span style="color:#0000ff;">/&gt;</span>
        <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">add</span> <span style="color:#ff0000;">key</span><span style="color:#0000ff;">="connection.connection_string"</span> <span style="color:#ff0000;">value</span><span style="color:#0000ff;">="Data Source=TIMESCOTT-PC\SQLEXPRESS;Initial Catalog=GrassRoots;Integrated Security=SSPI"</span><span style="color:#0000ff;">/&gt;</span>
      <span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">config</span><span style="color:#0000ff;">&gt;</span>
    <span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">facility</span><span style="color:#0000ff;">&gt;</span></pre>
</div>
<p>The other thing I am going to do is to get ActiveRecord to create the database schema for me. To do this I have added this line to Application_Start method in Global.asax. Now each time I start the application the tables are going to get dropped and recreated &#8211; so unless I want to re-generate the schema because of a change in the domain, I will comment this line out.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">ActiveRecordStarter.CreateSchema();</pre>
</div>
<p>There are much better ways to manage the database schema, but at this stage of the application I am not too worried about it. Something that I want to take some time to look at is <a title="Migrations for .Net" href="http://code.google.com/p/migratordotnet/">Migrations for .Net</a> as a solution to schema management.</p>
<p>A repository is a class that is only concerned with persisting and retrieving an object of a particular type. I have setup a generic interface IRepository&lt;T&gt; and an ActiveRecordRepository which implements it. Currently the interface only defines a Save method as this that is the only requirement I have for this stripe of development. Using the ActiveRecordMediator means that I only have to create this one class and that is all my repository layer needs to consist of. Here is the code:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Domain;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Core.Repositories
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">interface</span> IRepository&lt;T&gt; <span style="color:#0000ff;">where</span> T : IEntity
    {
        <span style="color:#0000ff;">void</span> Save(T instance);
    }
}</pre>
</div>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> Castle.ActiveRecord;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Domain;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Core.Repositories
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> ActiveRecordRepository&lt;T&gt; : IRepository&lt;T&gt; <span style="color:#0000ff;">where</span> T : <span style="color:#0000ff;">class</span>, IEntity
    {
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Save(T instance)
        {
            ActiveRecordMediator&lt;T&gt;.Save(instance);
        }
    }
}</pre>
</div>
<p>I don&#8217;t have any unit tests on the repositories themselves as they do not appear to be obviously unit testable. Having said that I don&#8217;t think this is a huge problem as it is a very small amount of code and this area will be covered by my integration tests.</p>
<h3>Mapping the User class to the database</h3>
<p>Now I have got my repository sorted I am now ready to wire up some classes to the database. I am going to do this using attributes in the classes. Here is the User class tagged with the necessary ActiveRecord attributes.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> Castle.ActiveRecord;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Core.Domain
{
    [ActiveRecord(<span style="color:#006080;">"`User`"</span>)]
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> User : EntityBase
    {
        [Property(NotNull = <span style="color:#0000ff;">true</span>)]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> Email { get; set; }

        [Property(NotNull = <span style="color:#0000ff;">true</span>)]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> FirstName { get; set; }

        [Property(NotNull = <span style="color:#0000ff;">true</span>)]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> Surname { get; set; }

        [Property(NotNull = <span style="color:#0000ff;">true</span>)]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> Phone { get; set; }
    }
}</pre>
</div>
<p>You might have noticed that the User class does not have an Id field, that is defined in its base class, EntityBase. The IEntity interface and EntityBase class are used to ensure that any object that is mapped to the database has the required fields. Currently all that consists of is an Id of type Guid. Here is the class diagram.</p>
<p><a href="http://timescott.files.wordpress.com/2008/08/domain.png"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://timescott.files.wordpress.com/2008/08/domain-thumb.png?w=361&#038;h=388" border="0" alt="domain" width="361" height="388" /></a></p>
<p>Okay, so all I need to do now is to create the database and run the application!</p>
<p>Just a note on choice of database engine&#8230;<br />
I am currently using SQL Server Express 2005, I wanted to have a play with SQLite as it seems far easier to deploy and much more lightweight. Has anyone had any experience with setting this up with ActiveRecord or found a good post about this? I have had a look around and tried to set it up but seemed to be unable to get hibernate to open a connection to the database. Anyway I will continue to try and get SQLite running with this project and will put up a post when I get it working.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/timescott.wordpress.com/71/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/timescott.wordpress.com/71/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/71/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=71&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/NbiTv3gIvp0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2008/08/06/tdd-with-monorail-part-6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2008/08/mappers-thumb.png" medium="image">
			<media:title type="html">mappers</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2008/08/domain-thumb.png" medium="image">
			<media:title type="html">domain</media:title>
		</media:content>
	</item>
		<item>
		<title>TDD with Monorail – Part 5</title>
		<link>http://timescott.wordpress.com/2008/08/06/tdd-with-monorail-part-5/</link>
		<comments>http://timescott.wordpress.com/2008/08/06/tdd-with-monorail-part-5/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 12:40:03 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Castle]]></category>
		<category><![CDATA[Monorail]]></category>
		<category><![CDATA[NUnit]]></category>
		<category><![CDATA[Rhino Mocks]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Unit Test]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/?p=64</guid>
		<description><![CDATA[Service Layer
Currently the responsibilities of my UserService are simply are to:

Validate the request
Map to a domain object
Delegate the actual work to fulfil the request to a repository

These requirements are reflected in my test for the Save method in the UserService:

using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;
using TimEscott.GrassRoots.Core.Domain;
using TimEscott.GrassRoots.Core.Mappers;
using TimEscott.GrassRoots.Core.Messages.Users;
using TimEscott.GrassRoots.Core.Repositories;
using TimEscott.GrassRoots.Core.Services;

namespace TimEscott.GrassRoots.Specs.Unit.Services
{
    [TestFixture]
   [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=64&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><h3>Service Layer</h3>
<p>Currently the responsibilities of my UserService are simply are to:</p>
<ul>
<li>Validate the request</li>
<li>Map to a domain object</li>
<li>Delegate the actual work to fulfil the request to a repository</li>
</ul>
<p>These requirements are reflected in my test for the Save method in the UserService:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;height:269px;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> NUnit.Framework;
<span style="color:#0000ff;">using</span> NUnit.Framework.SyntaxHelpers;
<span style="color:#0000ff;">using</span> Rhino.Mocks;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Domain;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Mappers;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Messages.Users;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Repositories;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Services;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Specs.Unit.Services
{
    [TestFixture]
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> When_saving_a_user : UnitTestBase
    {
        <span style="color:#0000ff;">private</span> MockRepository mockery;
        <span style="color:#0000ff;">private</span> IRepository&lt;User&gt; repository;
        <span style="color:#0000ff;">private</span> IUserMapper mapper;
        <span style="color:#0000ff;">private</span> UsersService service;

        [SetUp]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> SetUp()
        {
            mockery = <span style="color:#0000ff;">new</span> MockRepository();
            repository = mockery.DynamicMock&lt;IRepository&lt;User&gt;&gt;();
            mapper = mockery.DynamicMock&lt;IUserMapper&gt;();

            service = <span style="color:#0000ff;">new</span> UsersService(repository, mapper);
        }

        [Test]
        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Should_validate_the_save_user_request_save_a_user_and_return_a_valid_response()
        {
            var request = mockery.DynamicMock&lt;ISaveUserRequest&gt;();
            var user = userBuilder.BuildVaildObject();
            SaveUserResponse response;

            <span style="color:#0000ff;">using</span> (mockery.Record())
            {
                Expect.Call(() =&gt; request.Validate());
                Expect.Call(mapper.MapFrom(request)).Return(user);
                repository.Save(user);
            }

            <span style="color:#0000ff;">using</span> (mockery.Playback())
            {
                response = service.Save(request);
            }

            Assert.That(response.Success, Is.True);
        }
    }
}</pre>
</div>
<p>You&#8217;ll notice that I have given up with a convention that I stated using in an earlier post which was to call the system under test &#8217;subject&#8217;. I have chosen to give the fields names that give me some more context.</p>
<p>Writing this test has meant that I have needed to create a couple of other interfaces:</p>
<ul>
<li><strong>IUserMapper</strong> &#8211; will take a SaveUserRequest and return a valid User object</li>
<li><strong>IRepository&lt;User&gt;</strong> &#8211; will be able to persist users</li>
</ul>
<p>These were again mocked, to focus the test. Here is the implementation of the service:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Domain;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Mappers;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Messages.Users;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Repositories;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Core.Services
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> UsersService : IUsersService
    {
        <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">readonly</span> IRepository&lt;User&gt; repository;
        <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">readonly</span> IUserMapper mapper;

        <span style="color:#0000ff;">public</span> UsersService(IRepository&lt;User&gt; repository, IUserMapper mapper)
        {
            <span style="color:#0000ff;">this</span>.repository = repository;
            <span style="color:#0000ff;">this</span>.mapper = mapper;
        }

        <span style="color:#0000ff;">public</span> SaveUserResponse Save(ISaveUserRequest request)
        {
            request.Validate();

            repository.Save(mapper.MapFrom(request) <span style="color:#0000ff;">as</span> User);

            <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> SaveUserResponse(<span style="color:#0000ff;">true</span>);
        }
    }
}</pre>
</div>
<h3>UnitTestBase</h3>
<p>A point of interest about the unit test above is that it extends my UnitTestBase. UnitTestBase contains a number of protected fields for building objects used in the unit tests.</p>
<p>Some history behind this, I have worked on projects where the objects used in the tests are created as part of the setup or as part of the test itself each time one is required, resulting in a lot of duplicated code. I think that this approach is great in some respects as it clearly defines the intent of the test. But my concern was that if I were to make a change to the structure of a domain object, for example, then the number of changes that I would have to make to my tests just to get them to compile could be wide reaching. Maybe this is what you actually want because the tests are doing their job of highlighting changes to the behaviour and specifications of the code and forcing you to consider each case.</p>
<p>To counter some of this I am going to experiment with having some builder objects in UnitTestBase which I instantiate in the default constructor, which I can call to create valid or invalid objects of a particular type. As I said this is an experiment so we will have to re-evaluate in a few weeks and see if we can refactor and improve on the initial idea. I can already see that the number of these objects might grow rapidly so the management of them might be an issue, but in the spirit of YAGNI until I have a problem I am not going to try and fix it. I would also rather that the builder objects were instantiated during a setup rather than once in the constructor. I am also considering getting it to create mockery for me as well &#8211; more on this when I get round to refactoring it. For reference here is the current code for the TestUnitBase and a builder class and its interface:</p>
<p><strong>UnitTestBase</strong></p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Specs.Builders.Domain;
<span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Specs.Builders.Messages;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Specs.Unit
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">class</span> UnitTestBase
    {
        <span style="color:#0000ff;">protected</span> UserBuilder userBuilder;
        <span style="color:#0000ff;">protected</span> SaveUserRequestBuilder saveUserRequestBuilder;

        <span style="color:#0000ff;">protected</span> UnitTestBase()
        {
            userBuilder = <span style="color:#0000ff;">new</span> UserBuilder();
            saveUserRequestBuilder = <span style="color:#0000ff;">new</span> SaveUserRequestBuilder();
        }
    }
}</pre>
</div>
<p><strong>IBuilder &#8211; </strong>Can currently provide an Invalid and Valid object of type T.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Specs.Builders
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">interface</span> IBuilder&lt;T&gt;
    {
        T BuildVaildObject();
        T BuildInVaildObject();
    }
}</pre>
</div>
<p><strong>SaveUserRequestBuilder</strong></p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> TimEscott.GrassRoots.Core.Messages.Users;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Specs.Builders.Messages
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> SaveUserRequestBuilder : IBuilder&lt;SaveUserRequest&gt;
    {
        <span style="color:#0000ff;">public</span> SaveUserRequest BuildVaildObject()
        {
            <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> SaveUserRequest()
                       {
                           Email = <span style="color:#006080;">"tim.escott@gmail.com"</span>,
                           FirstName = <span style="color:#006080;">"Tim"</span>,
                           Surname = <span style="color:#006080;">"Escott"</span>,
                           Phone = <span style="color:#006080;">"09988776655"</span>
                       };
        }

        <span style="color:#0000ff;">public</span> SaveUserRequest BuildInVaildObject()
        {
            <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> SaveUserRequest()
                       {
                           Email = <span style="color:#0000ff;">null</span>,
                           FirstName = <span style="color:#0000ff;">null</span>,
                           Surname = <span style="color:#0000ff;">null</span>,
                           Phone = <span style="color:#0000ff;">null</span>
                       };
        }
    }
}</pre>
</div>
<p>A pretty short post this time looking at the service layer and the builder idea, in part 6 we will look at the repositories and the mappers.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/timescott.wordpress.com/64/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/timescott.wordpress.com/64/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/64/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=64&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/oev4zdxIHqA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2008/08/06/tdd-with-monorail-part-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>
	</item>
		<item>
		<title>TDD with Monorail – Part 4</title>
		<link>http://timescott.wordpress.com/2008/08/04/tdd-with-monorail-part-4/</link>
		<comments>http://timescott.wordpress.com/2008/08/04/tdd-with-monorail-part-4/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 21:48:15 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[FormHelper]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Messages]]></category>
		<category><![CDATA[Monorail]]></category>
		<category><![CDATA[Rhino Mocks]]></category>
		<category><![CDATA[Unit Tests]]></category>
		<category><![CDATA[Validation]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/?p=46</guid>
		<description><![CDATA[In part 4 I am going to look at extending the functionality of the user registration page. I am going to focus on capturing the data from the form, passing that data back to the server, persisting it and then informing the user of the results of the save. The result of this should be [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=46&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In part 4 I am going to look at extending the functionality of the user registration page. I am going to focus on capturing the data from the form, passing that data back to the server, persisting it and then informing the user of the results of the save. The result of this should be a small system that extends from the UI right the way to the database and back again.</p>
<p>Before we get into the code I just wanted to point out somethings about the application structure. Although the aim of this exercise is to ultimately end up with a functioning website, the website is not really the main focus of my development activities. The web project is really just a front end that sits on top of an engine/API, namely the core assembly. The core project is the thing that is actually doing most of the work and is therefore the part of the application that i am most concerned with. In order to keep the UI as abstracted from the core as possible I will need to be careful not to allow domain types to leak into the UI layer. Doing this means that I should, in theory, be able to swap UI&#8217;s in and out as I see fit. Using message objects is one way of abstracting actual domain implementation away from the UI. I think my messages will take the form of specific request and responses e.g. I will create SaveUserRequest and SaveUserResponse classes for the registration request and responses. These types will be the link between the UI and the core projects and are the beginnings of an API. I think this diagram should clarify my explanation of the application architecture.</p>
<p>The application shown with dependencies between the layers:</p>
<p style="text-align:center;"><a href="http://timescott.files.wordpress.com/2008/08/dependencies.png"><img class="size-medium wp-image-55 aligncenter" src="http://timescott.files.wordpress.com/2008/08/dependencies.png?w=300&#038;h=280" alt="Dependencies" width="300" height="280" /></a></p>
<p>and here are those message classes:</p>
<p style="text-align:center;"><a href="http://timescott.files.wordpress.com/2008/08/saveusermessages.png"><img class="size-medium wp-image-59 aligncenter" src="http://timescott.files.wordpress.com/2008/08/saveusermessages.png?w=300&#038;h=211" alt="" width="300" height="211" /></a></p>
<p>In addition to defining these two classes I have created an IValidatable interface which my SaveUserRequest implements. The reason for this is that I will be assuming that the SaveUserRequest objects will be coming from unknown sources therefore I am going to validate all requests before proceeding. The SaveUserRequest is deliberately thin at the moment, I will add more properties to it as required, but at this stage I am really just interested in getting all the layers functioning. Notice that my response class does not implement the IValidatable interface. The responses are generated by my core application so I am guaranteeing that all responses are valid just on the strength that I create them. I may revisit this assumption as things progress.</p>
<p>I am going to start driving out this particular bit of functionality this by creating a unit test around a &#8217;save&#8217; action in the UsersController. The save action will accept a SaveUserRequest object which will be populated with the data from the client and persist the data in the users table in the database. I already have an architecture in mind for the layers underneath the controllers so I will use a series of tests to try and flesh some of it out. Hopefully, once we are done this will get us all the way down to the database.</p>
<p>I know that I want to keep my controller&#8217;s actions as thin as possible, as I have already stated, the only concern that I want them to have is presentation. In order to keep to this, the persistence and mapping functionality will have to be delegated to another layer in the application. At this stage of development I do not know exactly how that other layer might function so I am going to use Rhino Mocks to mock its&#8217; functionality. This allows me to have a very focused unit test as I don&#8217;t need to worry about the implementation of the controllers dependencies. For the sake of the unit test I can assume that the dependencies work as expected thanks to the mock implementation.</p>
<p>I have chosen to use a service layer between my controllers and the rest of the application. They will act as a kind of gateway between the UI and the application. My current thinking it that I will probably need a service for each domain type, we&#8217;ll see how this turns out, anyway, here is the test I ended up with&#8230;</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">[Test]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Should_save_the_user_and_recieve_a_valid_response()
{
    var saveUserRequest = <span style="color:#0000ff;">new</span> SaveUserRequest();
    var saveUserResponse = <span style="color:#0000ff;">new</span> SaveUserResponse(<span style="color:#0000ff;">true</span>);

    <span style="color:#0000ff;">using</span> (mockery.Record())
    {
        Expect.Call(service.Save(saveUserRequest)).Return(saveUserResponse);
    }

    <span style="color:#0000ff;">using</span> (mockery.Playback())
    {
        controller.Save(saveUserRequest);
    }

    Assert.That(controller.PropertyBag[<span style="color:#006080;">"saveUserResponse"</span>], Is.InstanceOfType(<span style="color:#0000ff;">typeof</span>(SaveUserResponse)));
}</pre>
</div>
<p>As I am writing this application test first this test is dictating the implementation of my action, after creating all the types required by the test and running it, the implementation was the easy bit!</p>
<p>Here is the action:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">[AccessibleThrough(Verb.Post)]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Save([DataBindAttribute(<span style="color:#006080;">"saveUserRequest"</span>)] ISaveUserRequest saveUserRequest)
{
    PropertyBag[<span style="color:#006080;">"saveUserResponse"</span>] = userService.Save(saveUserRequest);
}</pre>
</div>
<p>Now we have a functioning action that gets a SaveUserRequest passed in, calls save on the UsersService and adds a SaveUserResponse object into the property bag. Good. The next stage is to look at the UserService, currently this doesn&#8217;t exist as all I had to do to satisfy the test was to create an interface with a save method on it.</p>
<p>I think the service layer will form the topic for the next post.</p>
<p>Just time for one quick aside&#8230;</p>
<h3>Form validation</h3>
<p>I have chosen to use jQuery&#8217;s excellent validation plugin, I chose it as it offers a non-invasive mechanism to validate my HTML form elements. By this I mean that I do not have to mess with my form elements or the code that creates them to hook in some client side validation. Using the rules mechanism provided by jQuery&#8217;s validation plugin I can setup exactly how my forms should be validated without getting in the way.</p>
<p>Here is an example of rules in action in my registration view:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">#capturefor(script)
    $(document).ready(function(){
        $("#saveUserRequestForm").validate({
            rules: {
                "saveUserRequest.FirstName": "required minlength(2) maxlength(255)",
                "saveUserRequest.Surname": "required minlength(2) maxlength(255)",
                "saveUserRequest.Email": "required email",
                "saveUserRequest.Phone": "required digits",
                "saveUserRequest.Password": "required minlength(6)",
                "confirm_password": {
                    equalTo: "#password"
                }
            }
        });
    });
#end

#capturefor(title)
  $resx.Headings_Registration
#end

$Form.FormTag("save.pnx", "%{id='saveUserRequestForm'}")
    $Form.LabelFor("saveUserRequest.FirstName", "$resx.Labels_FirstName") $Form.TextField("saveUserRequest.FirstName")
    $Form.LabelFor("saveUserRequest.Surname", "$resx.Labels_Surname") $Form.TextField("saveUserRequest.Surname")
    $Form.LabelFor("saveUserRequest.Email", "$resx.Labels_Email") $Form.TextField("saveUserRequest.Email")
    $Form.LabelFor("saveUserRequest.Phone", "$resx.Labels_Phone") $Form.TextField("saveUserRequest.Phone")
    $Form.LabelFor("saveUserRequest.Password", "$resx.Labels_Password") $Form.PasswordField("saveUserRequest.Password")
    $Form.LabelFor("confirm_password", "$resx.Labels_ConfirmPassword") $Form.PasswordField("confirm_password")
    $Form.Submit("$commonResx.Buttons_Submit", "%{id='submit'}")
<span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">form</span><span style="color:#0000ff;">&gt;</span></pre>
</div>
<p>As you can see my actual form elements are left well alone and the javascript validation just sits on top! &#8211; Nice.</p>
<p>You&#8217;ll notice that I am not using the FormHelper to write the closing form tag. This is because Monorail adds a bunch of validation code for the form that assumes that prototype.js is present on the client. I would rather Monorail didn&#8217;t spit out all of this javascript by default. Does anyone know a way of turning this off? I have had a look in the code and couldn&#8217;t see anything obvious.</p>
<p>jQuery&#8217;s validation plugin can be found at: <a title="jQuery validation plugin" href="http://plugins.jquery.com/project/validate">http://plugins.jquery.com/project/validate</a></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/timescott.wordpress.com/46/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/timescott.wordpress.com/46/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/46/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=46&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/yuu_8i4ZN8Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2008/08/04/tdd-with-monorail-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2008/08/dependencies.png?w=300" medium="image">
			<media:title type="html">Dependencies</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2008/08/saveusermessages.png?w=300" medium="image" />
	</item>
		<item>
		<title>Could not load type ‘Castle.MonoRail.TestSupport.BaseControllerTest’</title>
		<link>http://timescott.wordpress.com/2008/08/02/could-not-load-type-castlemonorailtestsupportbasecontrollertest/</link>
		<comments>http://timescott.wordpress.com/2008/08/02/could-not-load-type-castlemonorailtestsupportbasecontrollertest/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 11:55:29 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Castle]]></category>
		<category><![CDATA[Integration Tests]]></category>
		<category><![CDATA[Monorail]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/?p=41</guid>
		<description><![CDATA[Just thought I would post this as a reference for anyone else who gets the same problem. I had a bunch of integration tests that were running fine and using Monorail&#8217;s BaseControllerTest when all of a sudden I get:

Could not load type 'Castle.MonoRail.TestSupport.BaseControllerTest' from assembly 'Castle.MonoRail.TestSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'.
System.TypeLoadException: Could not load type 'Castle.MonoRail.TestSupport.BaseControllerTest' from [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=41&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Just thought I would post this as a reference for anyone else who gets the same problem. I had a bunch of integration tests that were running fine and using Monorail&#8217;s BaseControllerTest when all of a sudden I get:</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">Could not load type <span style="color:#006080;">'Castle.MonoRail.TestSupport.BaseControllerTest'</span> from assembly <span style="color:#006080;">'Castle.MonoRail.TestSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'</span>.
System.TypeLoadException: Could not load type <span style="color:#006080;">'Castle.MonoRail.TestSupport.BaseControllerTest'</span> from assembly <span style="color:#006080;">'Castle.MonoRail.TestSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'</span>. ...</pre>
</div>
<p>This seem to be caused by upgrading my project to use newer versions of the  Castle.MonoRail.TestSupport assembly. Luckily I found a post that helped me resolve the issue on the Castle forum. <a href="http://forum.castleproject.org/viewtopic.php?t=3352">http://forum.castleproject.org/viewtopic.php?t=3352</a>. The cause of the problem was that an older version of the Castle.MonoRail.TestSupport.dll was registered in my GAC.</p>
<p>To resolve the problem (on Vista) open the VS 2008 command prompt as admin and run:</p>
<p><strong>gacutil /u castle.monorail.testsupport</strong></p>
<p>This will uninstall the Castle.MonoRail.TestSupport.dll from your GAC, re-build your project and your tests should now run!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/timescott.wordpress.com/41/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/timescott.wordpress.com/41/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/41/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=41&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/qnXAKkn1SUo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2008/08/02/could-not-load-type-castlemonorailtestsupportbasecontrollertest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>
	</item>
		<item>
		<title>TDD with Monorail – Part 3</title>
		<link>http://timescott.wordpress.com/2008/07/17/tdd-with-monorail-part-3/</link>
		<comments>http://timescott.wordpress.com/2008/07/17/tdd-with-monorail-part-3/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 21:45:10 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Castle]]></category>
		<category><![CDATA[Monorail]]></category>
		<category><![CDATA[NUnit]]></category>
		<category><![CDATA[Specs]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[WatiN]]></category>
		<category><![CDATA[Windsor]]></category>

		<guid isPermaLink="false">http://timescott.wordpress.com/2008/07/17/tdd-with-monorail-part-3/</guid>
		<description><![CDATA[I have created a layout and stylesheet which will do for now, at least it will look like a system. I usually find that if I can have the html from a designer before starting on a page this helps smooth the development of the UI quite nicely.
Part 3 sees us create our first integration [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=35&subd=timescott&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I have created a layout and stylesheet which will do for now, at least it will look like a system. I usually find that if I can have the html from a designer before starting on a page this helps smooth the development of the UI quite nicely.</p>
<p>Part 3 sees us create our first integration spec. I am going to create a test which will check that there is a page at &#8220;&#8230;/Admin/Users/Register.pnx&#8221; and that the page has a title of &#8216;Register&#8217;.</p>
<p>A bit of housekeeping &#8211; I have setup IIS to use a virtual directory called &#8216;TimEscott.GrassRoots&#8217; which points to my web project directory, this virtual directory also has a ISAPI mapping setup on it for the &#8216;.pnx&#8217; extension, the file extension that I have chosen to use for my application, this is setup in IIS 7 using a script map. This file extension for the application is configured in the web.config, we are also refusing access to the view files themselves.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">&lt;</span><span style="color:#800000;">httpHandlers</span><span style="color:#0000ff;">&gt;</span>
      <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">add</span> <span style="color:#ff0000;">verb</span><span style="color:#0000ff;">="*"</span> <span style="color:#ff0000;">path</span><span style="color:#0000ff;">="*.pnx"</span> <span style="color:#ff0000;">type</span><span style="color:#0000ff;">="Castle.MonoRail.Framework.MonoRailHttpHandlerFactory, Castle.MonoRail.Framework"</span> <span style="color:#0000ff;">/&gt;</span>
      <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">add</span> <span style="color:#ff0000;">verb</span><span style="color:#0000ff;">="*"</span> <span style="color:#ff0000;">path</span><span style="color:#0000ff;">="*.vm"</span> <span style="color:#ff0000;">type</span><span style="color:#0000ff;">="System.Web.HttpForbiddenHandler"</span> <span style="color:#0000ff;">/&gt;</span>
<span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">httpHandlers</span><span style="color:#0000ff;">&gt;</span></pre>
</div>
<h2>Integration test class structure</h2>
<p>I have setup a IntegrationSpecsBase class which all my integration tests will inherit from. This gives some common functionality for building up URLs to pages in my system and inheriting all the useful stuff in Monorails BaseControllerTest. Here is my IntegrationSpecsBase class.</p>
<div style="border:1px solid gray;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;margin:20px 0 10px;padding:4px;">
<pre style="overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> Castle.MonoRail.TestSupport;

<span style="color:#0000ff;">namespace</span> TimEscott.GrassRoots.Specs.Integration
{
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">abstract</span> <span style="color:#0000ff;">class</span> IntegrationSpecsBase : BaseControllerTest
    {
        <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">string</span> BuildTestUrl(<span style="color:#0000ff;">string</span> path)
        {
            <span style="color:#0000ff;">const</span> <span style="color:#0000ff;">string</span> URL_FORMAT = <span style="color:#006080;">"http://localhost/TimEscott.GrassRoots/{0}"</span>;
            <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">string</span>.Format(URL_FORMAT, path);
        }
    }
}</pre>
</div>
<p>The requirement that I am going to tackle first is #6 &#8220;For unregistered Users to be able to register&#8221;. For this I will require a registration page on which a user will be able to submit some account details to create a new account. Now this is quite a large requirement and one which will need breaking down into smaller chunks before I can tackle it effectively. I am not going to document these smaller requirements here, I will let my tests document them.</p>
<h3>My User Registration specification</h3>
<p><a href="http://timescott.files.wordpress.com/2008/07/usersis1.png"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://timescott.files.wordpress.com/2008/07/usersis1-thumb.png?w=494&#038;h=388" border="0" alt="UsersIS1" width="494" height="388" /></a></p>
<p>The intention of the naming of the class and the test is that it should be able to read like a sentence. So this should read &#8220;When registering a user &lt;the&gt; users controller should display the registration view&#8221;. So the class name is very close in name to original specification #6. The intention is that the individual tests start to break down the over all requirement into smaller chunks that I can then go off and spec, test and then implement. I will experiment with naming the item under test, in this case the UsersController, subject and see how I feel about that particular convention as things move on further.</p>
<p>As you can see from the screen grab re-sharper is complaining somewhat about an undefined type, namely my UsersController. Well this will be because I haven&#8217;t created it yet being test first and all! So to satisfy the compiler I will go an create the UsersController class, re-sharper finds the newly created type and asks if I want to add a using statement to my testfixture, I add the using but still the compiler complains. I need to make the new UsersController inherit from the Monorail SmartDispatcherController. Now the compiler is happy I can finally run my tests.</p>
<p>I have a few tools available to me to run the tests, TestDriven.Net, NUnit GUI or the re-sharper test runner. I am going to experiment with all 3 until I find a favourite. I will run this test suite by using TestDriven, I have bound &#8220;Alt + T&#8221; to TestDriven to run the tests in context. Here are the results at this stage.</p>
<p><a href="http://timescott.files.wordpress.com/2008/07/usersis2tests.png"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="http://timescott.files.wordpress.com/2008/07/usersis2tests-thumb.png?w=493&#038;h=187" border="0" alt="UsersIS2tests" width="493" height="187" /></a></p>
<p>Right, well I know that I haven&#8217;t created the view, the action or put the text in the view. I was expecting the test to fail. So I am going to do the simplest thing I can to get the test to pass, I.e. Create the view, action and insert the text. After adding the new controller to the Windsor config, running the test again confirmed that I have satisfied this part of the overall specification.</p>
<p>Right that will do for this post, next time hopefully we will get a bit deeper into the architecture.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/timescott.wordpress.com/35/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/timescott.wordpress.com/35/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/timescott.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/timescott.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/timescott.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/timescott.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/timescott.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/timescott.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/timescott.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/timescott.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/timescott.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/timescott.wordpress.com/35/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=timescott.wordpress.com&blog=4245014&post=35&subd=timescott&ref=&feed=1" /></div><img src="http://feeds.feedburner.com/~r/timescott/~4/d0jniCzMII0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://timescott.wordpress.com/2008/07/17/tdd-with-monorail-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24e1dbc33da9eb1aea3a10f3273e8740?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">Tim</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2008/07/usersis1-thumb.png" medium="image">
			<media:title type="html">UsersIS1</media:title>
		</media:content>

		<media:content url="http://timescott.files.wordpress.com/2008/07/usersis2tests-thumb.png" medium="image">
			<media:title type="html">UsersIS2tests</media:title>
		</media:content>
	</item>
	</channel>
</rss>
