Wednesday, January 19, 2011

Using StructureMap Automocker To Make Writing Tests fun.

I have for a period of time been a big fan of Jeremy Miller’s StructureMap library for Dependency Injection/Inversion Of Control. I particularly enjoy the Auto Registration and Type Scanning features of the library.

For instance within the Data Layer a registry such as:
[sourcecode language="csharp"]
public class DataRegistry : Registry
{
public DataRegistry()
{
Scan(x => { x.AddAllTypesOf(); x.ConnectImplementationsToTypesClosing(typeof(IRepository)); x.TheCallingAssembly(); });
}
}
[/sourcecode]

This class, which inherits from StructureMap.Configuration.DSLRegistry, will scan the types in the assembly that contains the Data Registry class, adds all implementations of IQuery to the the container and connects all implementation to the open generic IRepository.

I have recently discovered another feature that makes StructureMap one of my essential tools in my Development Toolkit. The aforementioned feature is Automocker, which comes in flavours such as RhinoAutoMocker and MoqAutoMocker. Automocker repurposes an IoC container to automate the creation and attachment of mock objects to a concrete class within unit tests. Certainly is a mouthful but hopefully an example will shed some light on the some of the advantages.

Let’s say you are writing Unit Tests for a Child Sponsorship website for Worldvision (something that happens quite a bit to me) and you have a class whose responsibility is to lock a user chosen child so that the child cannot be sponsored by another user of the site.

The class could look something like this:
[sourcecode language="csharp"]
public class ChildChosenForSponsorshipCommandHandler : ICommandHandler
{
private readonly IRepository _childRepository;
private readonly IChildOnHoldTimer _childOnHoldTimer;

public ChildChosenForSponsorshipCommandHandler(IRepository childRepository, IChildOnHoldTimer childOnHoldTimer)
{
_childRepository = childRepository;_
childOnHoldTimer = childOnHoldTimer;
}

public void Handle(Child child)
{
_childRepository.PlaceChildOnHold(child);
_childOnHoldTimer.Start();
}
}
[/sourcecode]

One test which could be written for this user story is
[sourcecode language="csharp"]
[Test]
public void ShouldPlaceChildOnHoldWhenChildIsChosenForSponsorship()
{
//arrangevar mockChildRepostory = MockRepository.GenerateMock();
var mockChildOnHoldTimer = MockRepository.GenerateMock();
var childChosenForSponsorshipCommandHandler = new ChildChosenForSponsorshipCommandHandler(mockChildRepostory,mockChildOnHoldTimer);

var child = new Core.Handlers.Child();

//actchildChosenForSponsorshipCommandHandler.Handle(child);

//assertmockChildRepostory.AssertWasCalled(x => x.PlaceChildOnHold(child));
}
[/sourcecode]

The way in which can be written using StructureMap’s AutoMocker assembly is:
[sourcecode language="csharp"]
[Test]
public void ShouldPlaceChildOnHoldWhenChildIsChosenForSponsorship()
{
//arrangevar childChosenForSponsorshipCommandHandler = new RhinoAutoMocker();

var child = new Core.Handlers.Child();

var classUnderTest = childChosenForSponsorshipCommandHandler.ClassUnderTest;

//actclassUnderTest.Handle(child);

//assertchildChosenForSponsorshipCommandHandler.Get().AssertWasCalled(x=>x.PlaceChildOnHold(child));
}
[/sourcecode]

A whole ONE line less code, I’ll have that new feature out before lunch! On the surface in may not look like much but if the class under test (CUT) has three, four or more dependencies you’ve made the arranging of the Unit Test much easier. The greatest benefit of the AutoMocker that I can see is that it helps keep the content of your tests focused on what needs to be tested, the functionality of your system. It also helps to keep your tests less brittle as your objects evolve. That is, if you add another dependency as your code evolves and you’ve got 15 tests under this Test Fixture you won’t have 15 tests to fix so that you can get the green light. In other words you can concentrate on what is important the context of the next test.

Monday, January 3, 2011

MVC: Making my life a bit easier using UrlHelper and HtmlHelperExtensions

In this post I’m going to outline some of the Extension methods that I use to make my life a bit easier when authoring views pages in MVC.

Through the process of developing code I do my best to avoid “Magik Str!ngs”.. sorry I mean “Magic Strings”. They are prone to misspellings and can add a headache especially if you have variants of the some Html snippet throughout your views that can be avoided with some forethought.

For View pages in MVC I do my best to avoid

[sourcecode language="html"]
<link href="/css/sidebar.css" id="Link1" rel="Stylesheet" type="text/css" />
<link href="/css/styles.css" id="cssStyleSheet" rel="Stylesheet" type="text/css" />
<link href="/css/custom-theme/jquery-ui-1.7.2.custom.css" type="text/css" rel="stylesheet" />
<link href="/css/standard.css" rel="stylesheet" type="text/css" />
<link href="/css/custom-theme/jquery-ui-1.7.2.custom.css" type="text/css" rel="Stylesheet" />

@Html.ActionLink("About", "About", "Home")
[/sourcecode]

To help me avoid passing the controller, action or route name as string, I create extension methods for UrlHelper and HtmlHelper to encapsulate the required Html Output:

[sourcecode language="csharp"]
public static class UrlHelperExtension
{
public static string About(this UrlHelper urlHelper)
{
return urlHelper.Action("About", "Home");
}
}
[/sourcecode]

Combining this with a HtmlExtension:

[sourcecode language="csharp"]
public static class HtmlHelperExtension
{
public static IHtmlString AnchorLink(this HtmlHelper htmlHelper, string url, string anchorDisplayName)
{
return new HtmlString("<a href=\"{0}\">{1}</a>".FormatWith(url, anchorDisplayName));
}
}
[/sourcecode]

I use an extension method called “AnchorLink” to which I pass two string variables, one for the required Url and another for the display text for the anchor link. Note that I also use IHtmlString. If I returned a string object from this method I would always have to remember to use Html.Raw or HtmlString in my views, which certainly opens up the possibility of adding some rendering issues to some of the views.

[sourcecode language="html"]
@Html.AnchorLink(Url.About(), "About")
[/sourcecode]

which will output the following HtmlSnippet

[sourcecode language="html"]
<a href="/Home/About">About</a>
[/sourcecode]

I use a similar pattern for Css and Javascript registration in the Views using the following signatures:

[sourcecode language="csharp"]
public static IHtmlString StyleSheet(this UrlHelper urlHelper, string css)

public static IHtmlString Javascript(this UrlHelper urlHelper, string js)
[/sourcecode]

then in my view for the registration of css I just use

[sourcecode language="csharp"]
@Url.StyleSheet("style.css")
[/sourcecode]

I will also register the Namespace of my Helpers in the config file. If you are using the Razor ViewEngine note that the namespace needs to be be registered as such

[sourcecode language="xml"]
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="CUSTOM_NAMESPACE_HERE" />
</namespaces>
</pages>
</system.web.webPages.razor>
[/sourcecode]

Hope this post helps someone else’s development sanity.