Azure Insights

I’ve launched a new blog and it’s all about Microsoft Azure.

If you want to learn Azure but don’t know where to start, Azure Insights is here to help. We’ll cover all the basics. If you’re just getting started then the Azure Bites series will help you grok key concepts like Web Apps and App Services.

If you’re already using Azure but want to expand your knowledge then we’ll cover more in depth concepts such as building Microservices and hosting them in Azure.

We’re just getting started so please take a look and let me know what you think. Also, if there are specific topics you’d like to see covered please do get in touch.

Azure Insights

Rendering razor templates on the fly

Dynamic content

Every now and then you need a way to generate some content using a template.

The obvious example which springs to mind is the humble email. You know, the kind you get when you register with a site, or tell them you’ve forgotten your password.

I’ve made and seen various attempts to tackle this. You can try simply looking for tokens and replacing them with content.

For example…

Dear $title$

Then write some code to find $title$ and replace it with “Mr”, “Mrs” etc.

Once you start down this path  you soon realise that you’re re-inventing a templating engine, and that’s a problem which has already been solved.

Step in Razor

So one option is to let Razor do the hard work for you.

A quick google reveals several libraries which can help, one of them is Razor Templates

Here’s an example of it’s usage…

dynamic model = new ExpandoObject();
model.Title = "Mr";
var templateContents = "Dear @Model.Title";

var compiledTemplate = RazorTemplates.Core.Template
.WithBaseType<TemplateBase>()
.Compile(templateContents);

var output = compiledTemplate.Render(model);

Compiling the template is quite an expensive operation so a bit of caching doesn’t go amiss here. In my case I just used a dictionary, base 64 encoded the template contents to use as a key and made sure to only recompile the template if the contents (key) change.

And that’s it, all the power of razor (loops, conditionals etc) is yours to use as you see fit.

When it comes to storing the templates, a NoSQL DB works nicely here.

 

 

Rendering razor templates on the fly

Azure Local Deployment Service Channel Faulted

Sometimes when deploying an Azure project to the local compute emulator I’ve seen this error message.

“The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.”

It’s a horrible error and I haven’t been able to fix it using any of the methods found via google (e.g. “your web.config may be readonly” or “your project might have too many files in it”).

The only solution I’ve found is to do a fresh checkout of the source code from TFS

Fix

Go to Source Control Explorer, right click on your collection and select Advanced – Remove Mapping

Remove Mapping

 

Now enter a new Local folder and click Change.

ChangeBinding

After a short time, Visual Studio will pull down a fresh copy of your source code into this new folder.

I have found that the next time I build and run the project, the error doesn’t appear and everything works as it should.

 

Azure Local Deployment Service Channel Faulted

ASP.NET and JQuery MVC Menu Part 3 (AJAX)

Other posts in this series:

Aaron has very kindly sent me an extension to the original code for creating a simple menu for ASP.NET MVC sites. His version employs the Microsoft AJAX library to “ajaxify” the links on the menu.

The main part of his code handles getting a List Item containing an AJAX link.

public static class Extention
    {
        public static TagBuilder GetNavItem(this AjaxHelper ajax, MolineSoftware.SLAudit.Navigation navItem)
        {
            MvcHtmlString htmlTemplate = null;
            if (navItem.Route == null)
            {
                htmlTemplate =
                    ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller,
                                    new AjaxOptions
                                        {
                                            UpdateTargetId = navItem.UpdateTargetId,
                                            OnSuccess = navItem.OnSuccess,
                                            OnBegin = navItem.OnBegin
                                        });
            }
            else
            {
                htmlTemplate =
                    ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller, navItem.Route,
                                    new AjaxOptions
                                        {
                                            UpdateTargetId = navItem.UpdateTargetId,
                                            OnSuccess = navItem.OnSuccess,
                                            OnBegin = navItem.OnBegin
                                        });
            }
            var builder = new TagBuilder("li");
            if (IsCurrentAction(ajax, navItem.ActionName, navItem.Controller))
                builder.MergeAttribute("class", "current");
            builder.InnerHtml = htmlTemplate.ToHtmlString();
            return builder;
        }
        static bool IsCurrentAction(AjaxHelper ajax, string actionName, string controllerName)
        {
            string currentControllerName = (string) ajax.ViewContext.RouteData.Values["controller"];
            string currentActionName = (string) ajax.ViewContext.RouteData.Values["action"];
            if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) &&
                currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
            {
                return true;
            }
            return false;
        }
    }
}

You will notice the use of a class called Navigation (to build the actual link).

public class Navigation
{
    #region | Public Properties |
    /// <summary>
    /// Gets or Sets the ID
    /// </summary>
    public virtual Int32 Id { get; set; }
    /// <summary>
    /// Gets or Sets the Display for the link
    /// </summary>
    public virtual String LinkText { get; set; }
    /// <summary>
    /// Gets or Sets the ActionName.
    /// </summary>
    public virtual String ActionName { get; set; }
    /// <summary>
    /// Gets or Sets the Controller
    /// </summary>
    public virtual String Controller { get; set; }
    /// <summary>
    /// Gets or sets the Active flag.
    /// </summary>
    public virtual Boolean Active { get; set; }
    /// <summary>
    /// Gets or sets the JavaScript function to call after the page is successfully updated.
    /// </summary>
    public virtual String OnSuccess { get; set; }
    /// <summary>
    /// Gets or sets the name of the JavaScript function to call immediately before the page is updated.
    /// </summary>
    public virtual String OnBegin { get; set; }
    /// <summary>
    /// Gets or sets the ID of the DOM element to update by using the response from the server.
    /// </summary>
    public virtual String UpdateTargetId { get; set; }
    /// <summary>
    /// Gets or Sets the <see cref=”RouteValueDictionary”/>
    /// </summary>
    public virtual object Route { get; set; }
    #endregion
}

We can then create a collection of these navigation items…

namespace MolineSoftware.SLAudit
{
    public class NavigationList : List<Navigation>
    {
        #region | Constructor |
        #endregion
        ///Returns a NavigationList of items ** TESTING ONLY
        public NavigationList GetTestList()
        {
            NavigationList list = new NavigationList();
            list.Add(new Navigation
                         {
                             Active = true,
                             Controller = “Home”,
                             OnBegin = “SetLoading”,
                             OnSuccess = “handleUpdate”,
                             Id = 1,
                             LinkText = “Home”,
                             ActionName = “Index”,
                             UpdateTargetId = “output-data”,
                             Route = new {serverName = “MyServer”} //Example setting the route object
                         });
            list.Add(new Navigation
                         {
                             Active = true,
                             Controller = “Home”,
                             OnBegin = “SetLoading”,
                             OnSuccess = “handleUpdate”,
                             Id = 2,
                             LinkText = “About”,
                             ActionName = “About”,
                             UpdateTargetId = “output-data”
                         });
            return list;
        }
    }

Finally we can use this code (assuming model is an instance of our NavigationList class) to render the menu.

<% foreach (var menu in Model as MolineSoftware.SLAudit.NavigationList) { %>
    <%= Ajax.GetNavItem(menu)%>
<% } %>
ASP.NET and JQuery MVC Menu Part 3 (AJAX)

Upgrading to ASP.NET MVC 2/.net 4

We have recently upgraded a few projects to .net 4 (and MVC 2) and have invariably hit one particular error message.

We are using the Spark view engine, and having upgraded the project to MVC 2 would see this error…

Dynamic view compilation failed. (0,0): warning CS1701: Assuming assembly reference ‘System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ matches ‘System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’, you may need to supply runtime policy

Google helped us find this post, which explains that any referenced assemblies which in turn reference MVC 1 could be causing this issue.

After a prolonged process of checking and upgrading various assemblies, we eventually discovered that we needed to update our _Global.spark file.

This file (for those who haven’t used it) is a useful place to put anything which all the spark pages in your project need to include.

Ours looked like this…

<use namespace="Microsoft.Web.Mvc" />
<use namespace="MvcContrib" />
<use namespace="MvcContrib.UI" />
<use namespace="MvcContrib.UI.Pager" />
<use namespace="MvcContrib.FluentHtml" />
<use namespace="System" />
<use namespace="System.Data" />
<use namespace="System.Collections.Generic" />
<use namespace="System.Web.Mvc" />
<use namespace="System.Web.Mvc.Html" />
<use namespace="Autoclimate.Framework.Extensions" />
<use namespace="Catalogue.Web.Code" />
<use namespace="xVal.Html" />

We’d upgraded most of these to the latest versions, except for xVal. Removing xVal from this list fixed the problem. As it happens we were no longer using xVal (in the spark pages) so we didn’t need it in there anyway.

Upgrading to ASP.NET MVC 2/.net 4

Posting an Array of Complex types using JQuery, JSON to ASP.NET MVC

I recently hit a requirement to take an array of objects and post them to an asp.net mvc action using JQuery’s ajax functionality.

I had to do a bit of Googling to work out how to do this so figured I’d document what I found.

The main two parts to this are getting JQuery to spit out JSON data and ASP.NET MVC to deserialize that data into a strongly typed generic list.

Javascript (JQuery)

$('#saveChanges').click(function () {
    var rules = new Array();
 
    $('#assignedRules table.ruleTable tbody tr').each(function (i) {
        var subRuleCode = $('#subRuleCode', this).val();
        var productGroupId = $('#productGroupId', this).val();
        rules.push(new Rule(subRuleCode, productGroupId));
    });
 
    var postData = JSON.stringify(rules);
 
    $.ajax({
        url: '/rule/SaveUserRules',
        data: postData,
        contentType: 'application/json',
        dataType: 'json',
        type: 'post',
        success: onRulesSaved,
        error: function (data, textStatus) { alert(textStatus); }
    }
    );
});

This javascript

  • creates a new array
  • iterates over some table rows and grabs a couple of hidden field values for each row
  • stores the hidden field values in a javascript class called Rule
  • pushes the Rule instance into the array
  • calls JSON.stringify to construct a valid JSON string from our array of Rules
  • posts the JSON string to our destination URL

As you can see, this script effectively translates a table of values, to an array of Rules which are then sent as JSON to our target URL.

The stringify function uses the script available from here.

The Rule javascript class is simple enough…

function Rule(subRuleCode, productGroupId) {
    this.SubRule = subRuleCode;
    this.ProductGroupId = productGroupId;
}

MVC Action

The next trick is to get the MVC action to accept the array and turn it into a strongly typed generic list.

[AcceptVerbs(HttpVerbs.Post)]
public JsonResult SaveUserRules(List<Rule> usersRules)
{
    // do something here
}

As you can see we simply specify our generic list as the parameter for our action (which accepts HTTP Posts only).

JSON Model Binder

The final piece in the jigsaw is to tell MVC how to bind the JSON data to this generic list of Rules.

I found the code to create a simple JSON model binder here.

public class JsonModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (!IsJSONRequest(controllerContext))
        {
            return base.BindModel(controllerContext, bindingContext);
        }
        // get the JSON data that’s been posted
        var request = controllerContext.HttpContext.Request;
        var jsonStringData = new StreamReader(request.InputStream).ReadToEnd();
        return new JavaScriptSerializer()
            .Deserialize(jsonStringData, bindingContext.ModelMetadata.ModelType);
    }
    static bool IsJSONRequest(ControllerContext controllerContext)
    {
        var contentType = controllerContext.HttpContext.Request.ContentType;
        return contentType.Contains(“application/json”);
    }
}

Now all you have to do is register this as the default model binder. Because it inherits the DefaultBinder, and only kicks in if the request type is application/json this shouldn’t break any non-json model binding.

void AddModelBinders()
{
    ModelBinders.Binders.DefaultBinder = new JsonModelBinder();
}
Posting an Array of Complex types using JQuery, JSON to ASP.NET MVC

BDD with MSpec and Rhino Auto Mocks (part 3)

In part 1 and part 2 we covered setting up MSpec, writing our specifications and then implementing one of those specifications.

So far we’ve covered very simple tests for code which has no external dependencies and does very little. Now we’ll turn our attention to those tests which (on the face of it) are more complicated and cover code which relies on data access, email services etc.

Lets tackle the the “when asked for products matching search term” specification.

Establishing Context

As before, we’ll start by establishing the context for this test, and to cut down on duplication, I’ve moved the basic context setup to its own class.

  1. public class concern_for_product_controller
  2. {
  3.     protected static ProductController _controller;
  4.  
  5.     Establish context =
  6.         () => { _controller = new ProductController(); };
  7. }

Now we can make all of the Product Controller tests inherit this class.

  1. [Subject("Product Search")]
  2. public class when_asked_for_products_matching_search_term : concern_for_product_controller
  3. {
  4.     It should_retrieve_a_list_of_products_with_titles_containing_the_search_term;
  5.     It should_return_the_list_of_products_to_the_user;
  6. }

To implement the specification “should retrieve a list of products…” we want to simply check that the controller asks for a list of products from wherever we’re hoping to get our data from.

In the spirit of writing tests first we haven’t got any kind of data access layer yet so now we decide we need a Product Repository.

Rhino AutoMocker

To help test our repository we can introduce Rhino AutoMocker to the equation. Rhino AutoMocker is included as part of an AutoMocking library distributed with StructureMap.

To use it in your project, simply download StructureMap and reference StructureMap.AutoMocking and Rhino.Mocks in your project.

We need to wire up the automocker so we can use it in our tests. To that end we’ll change our base class.

  1. public class concern_for_product_controller
  2. {
  3.     protected static ProductController _controller;
  4.     protected static IProductRepository _productRepository;
  5.     static RhinoAutoMocker<ProductController> mocker;
  6.  
  7.     Establish context =
  8.         () =>
  9.             {
  10.                 mocker = new RhinoAutoMocker<ProductController>();
  11.                 _controller = mocker.ClassUnderTest;
  12.                 _productRepository = mocker.Get<IProductRepository>();
  13.             };
  14. }

So what’s going on here?

  1. We’ve introduced an instance of the AutoMocker for our Product Controller.
  2. To make life easier we’ve introduced a field which references the AutoMocker’s “class under test” (in this case our Product Controller).
  3. We’ve asked AutoMocker for an instance of IProductRepository and also referenced this as a handy field (which we can use in our tests).

Now we can turn our attention back to the test.

Setting Expectations

  1. static ActionResult _result;
  2.  
  3.  Because of =
  4.      () => { _result = _controller.Search("test"); };
  5.  
  6.  It should_retrieve_a_list_of_products_with_titles_containing_the_search_term =
  7.      () => _productRepository.AssertWasCalled(x => x.FindProducts("test"));

  1. We call a new overloaded version of our controller’s Search method (which accepts a string search term).
  2. Then we perform a simple check to assert that the FindProducts method was called on IProductRepository.

Finally, we want to check what gets sent back to the view. For now we’ll simply check the name of the view being returned (and that the result is a view).

  1. It should_return_the_list_of_products_to_the_user =
  2.     () => _result.is_a_view_and().ViewName.ShouldEqual("SearchResults");

As I’ve gone along here I’ve implemented just enough to have the test compile.

IProductRepository
  1. public interface IProductRepository
  2. {
  3.     IList<Product> FindProducts(string searchTerm);
  4. }

ProductController
  1. public ActionResult Search(string searchTerm)
  2. {
  3.     throw new NotImplementedException();
  4. }

At this point we want to make the test pass so let’s do that.

  1. readonly IProductRepository _productRepository;
  2.  
  3. public ProductController(IProductRepository productRepository)
  4. {
  5.     _productRepository = productRepository;
  6. }
  7.  
  8. public ActionResult Search(string searchTerm)
  9. {
  10.     return View("SearchResults", _productRepository.FindProducts(searchTerm));
  11. }

Now our MSpec tests will pass.

When we run the tests, AutoMocker will generate a mocked version of our IProductRepository which our test uses to assert which methods were called. By letting AutoMocker generate our mocks we cut down on a lot of boilerplate code but don’t really loose anything in terms of flexibility and control (we can manually add mocks if we don’t want AutoMocker handling them for us).

Stubs

Now lets say we want to check that the list of products retrieved from the repository is actually sent back with the view.

For this, we can set up the automocked IProductRepository to return a specific list of products which we can then check are sent back to the user.

Lets start by telling automocker to stub the Search method and return a new list of products.

  1. Establish context =
  2.     () =>
  3.         {
  4.             _products = new List<Product>();
  5.             _productRepository.Stub(x => x.FindProducts("test")).Return(_products);
  6.         };

  1. We’ve added an Establish Context to our test (this will be used in conjunction with the one in our base class)
  2. We’ve said that when the FindProducts method is called with the parameter “test” then a new generic list of Product will be returned

Now we’ll change the implementation of the spec to check that this same list of products is returned with the view. Whilst we’re at it we’ll move the test for the view’s name into it’s own specification.

  1. It should_return_the_list_of_products_to_the_user =
  2.     () => _result.is_a_view_and().ViewData.Model.ShouldEqual(_products);
  3.  
  4. It should_return_the_search_results_page_to_the_user =
  5.     () => _result.is_a_view_and().ViewName.ShouldEqual("SearchResults");

Putting it all together

So finally, our completed test implementation now looks like this…

  1. [Subject("Product Search")]
  2. public class when_asked_for_products_matching_search_term : concern_for_product_controller
  3. {
  4.     static List<Product> _products;
  5.     static ActionResult _result;
  6.  
  7.     Establish context =
  8.         () =>
  9.             {
  10.                 _products = new List<Product>();
  11.                 _productRepository.Stub(x => x.FindProducts("test")).Return(_products);
  12.             };
  13.  
  14.     Because of =
  15.         () => { _result = _controller.Search("test"); };
  16.  
  17.     It should_retrieve_a_list_of_products_with_titles_containing_the_search_term =
  18.         () => _productRepository.AssertWasCalled(x => x.FindProducts("test"));
  19.  
  20.     It should_return_the_list_of_products_to_the_user =
  21.         () => _result.is_a_view_and().ViewData.Model.ShouldEqual(_products);
  22.  
  23.     It should_return_the_search_results_page_to_the_user =
  24.         () => _result.is_a_view_and().ViewName.ShouldEqual("SearchResults");
  25. }

Hopefully these posts have demonstrated how well MSpec and Rhino AutoMocker can work together. The key is that the tests are easy to maintain and clearly state the criteria by which to judge whether the code under test is valid.

These criteria are stated as human understandable specifications which can be agreed with your users before writing any code. RhinoAutoMocker makes mocking and stubbing very straightforward and helps you to defer making decisions until the last responsible moment.

You will find the source code for this sample project on GitHub.

BDD with MSpec and Rhino Auto Mocks (part 3)

BDD with MSpec and Rhino Auto Mocks (part 2)

In part 1, we looked at setting up MSpec and writing our first specifications.

Now we get on to the all important implementation stage.

We ended up with these basic specifications by the end of part 1.

  1. using Machine.Specifications;
  2.  
  3. namespace MSpecExample.Tests.Controllers
  4. {
  5.     [Subject("Product Search")]
  6.     public class when_product_search_page_requested
  7.     {
  8.         It should_return_product_search_page;
  9.     }
  10.  
  11.     [Subject("Product Search")]
  12.     public class when_asked_for_products_matching_search_term
  13.     {
  14.         It should_retrieve_a_list_of_products_with_titles_containing_the_search_term;
  15.         It should_return_the_list_of_products_to_the_user;
  16.     }
  17.  
  18.     [Subject("Product Search")]
  19.     public class when_empty_search_term_entered
  20.     {
  21.         It should_return_an_error_message;
  22.     }
  23. }

Lets start by implementing the first one (when product search page requested).

  1. [Subject("Product Search")]
  2. public class when_product_search_page_requested
  3. {
  4.     static ProductController _controller;
  5.  
  6.     Establish context =
  7.         () => {
  8.             _controller = new ProductController();
  9.         };
  10.  
  11.     It should_return_product_search_page;
  12. }

On first glance, the wacky syntax here might put people off. However, once you start writing these tests you tend to see past it to the specs and the tests themselves.

We start by establishing the context for our test, what we need for this test to actually run. In this case it’s the product controller that we’re testing, and so it makes sense to instantiate the product controller and assign it to a field for use within our tests.

Next we need to actually do something, perform the action which we are testing. In this case we’re talking about the user visiting the “product search page” so I will set up the test to call an action on the product controller called Search.

  1. [Subject("Product Search")]
  2. public class when_product_search_page_requested
  3. {
  4.     static ProductController _controller;
  5.     static ActionResult _result;
  6.  
  7.     Establish context =
  8.         () => { _controller = new ProductController(); };
  9.  
  10.     Because of =
  11.         () => { _result = _controller.Search(); };
  12.  
  13.     It should_return_product_search_page;
  14. }

Note how we have created a Because statement. In BDD terms this is the behaviour we are testing. As with the controller I store the result of calling this action in a field so we can use it elsewhere in the test.

At this point I should point out that in the spirit of TDD, I am only doing enough at this point to make this compile. So our Product Controller currently looks like this.

  1. public class ProductController : Controller
  2. {
  3.     public ActionResult Search()
  4.     {
  5.         throw new NotImplementedException();
  6.     }
  7. }

Jumping back to our test, lets test that the behaviour under test (search) does what we expect.

  1. [Subject("Product Search")]
  2. public class when_product_search_page_requested
  3. {
  4.     static ProductController _controller;
  5.     static ActionResult _result;
  6.  
  7.     Establish context =
  8.         () => { _controller = new ProductController(); };
  9.  
  10.     Because of =
  11.         () => { _result = _controller.Search(); };
  12.  
  13.     It should_return_product_search_page =
  14.         () => { _result.is_a_view_and().ViewName.ShouldEqual("Search"); };
  15. }

Using an extension method (thank you James Broome and JP Boodhoo) we can simultaneously check that our result is a view and also get a typed reference to the result (as a ViewResult).

  1. public static class TestExtensions
  2. {
  3.     public static ViewResult is_a_view_and(this ActionResult result)
  4.     {
  5.         return result as ViewResult;
  6.     }
  7. }

Now we make the test pass.

  1. public class ProductController : Controller
  2. {
  3.     public ActionResult Search()
  4.     {
  5.         return View("Search");
  6.     }
  7. }

Finally we run MSpec and marvel at the results 😉

image

We still have several not implemented specs, but the one we have implemented now appears as a simple line of text. If there were any problems with the test (if it failed) we would see a red error message by the failing specification.

In part 3 we’ll look at more complex controller actions and introduce Rhino Auto Mocker.

BDD with MSpec and Rhino Auto Mocks (part 2)

BDD with MSpec and Rhino Auto Mocks (part 1)

I’ve long been a fan of test driven development in theory but in practice have experienced many of the issues which turn people off TDD and unit testing in general.

Brittle tests which do too much, tell you very little about the meaning behind the code and are more a hindrance than a help when it comes to making changes at a later date.

Well as you may have guessed, given the title of this post, I have found an answer to these problems in the form of BDD using MSpec and Rhino Automocking. I have been using this approach for a good while now and continue to be pleasantly surprised by just how much fun it is writing my tests, but also how stupidly easy they are to change, and how well they document my project’s requirements.

Update: You can get MSpec from github.

External Tool

It’s a good idea to set up an external tool in Visual Studio to run your MSpec tests and produce html output.

Create a new external tool which launches mspec.exe with the following arguments.

$(TargetName)$(TargetExt) --html "$(ProjectDir)\Report.html"

Make sure the initial directory is $(BinDir) and tick Use output window.

image 

Using your favourite Test Runner

Included in the MSpec download are scripts to configure various test runners to recognise and run MSpec tests.

image

Simply run the bat file which relates to your build runner and way you go!

Writing Specifications

Ensure you add a reference (in your Tests Project) to Machine.Specifications.dll.

Now the fun begins.

I’ve created an ASP.NET MVC site and empty class library Tests project.

Let’s say we want to create a simple page which allows users to search for a product.

We’ll start by creating a new folder in our tests folder called Controllers and add a new class file called ProductControllerTets.cs

Having discussed this feature in detail with the client, I’ve a pretty good idea of what they want, so I start with the following.

  1. using Machine.Specifications;
  2.  
  3. namespace MSpecExample.Tests.Controllers
  4. {
  5.     [Subject("Product Search")]
  6.     public class when_product_search_page_requested
  7.     {
  8.         It should_return_product_search_page;
  9.     }
  10.  
  11.     [Subject("Product Search")]
  12.     public class when_asked_for_products_matching_search_term
  13.     {
  14.         It should_retrieve_a_list_of_products_with_titles_containing_the_search_term;
  15.         It should_return_the_list_of_products_to_the_user;
  16.     }
  17.  
  18.     [Subject("Product Search")]
  19.     public class when_empty_search_term_entered
  20.     {
  21.         It should_return_an_error_message;
  22.     }
  23. }

What I particularly like about this, is that you can really think about exactly what you’re doing and express it in code which will eventually become executable tests without actually implementing any code (yet!).

If we now build our test project and run the tests using the console runner via the external tool we set up earlier), we’ll get a report.html file in the tests project which looks like this…

image

In part 2, we’ll start implementing these tests.

In part 3, we’ll introduce Rhino AutoMocker.

BDD with MSpec and Rhino Auto Mocks (part 1)