Welcome to EMC Consulting Blogs Sign in | Join | Help

James Broome Blog

  • New blog site

    So after a year or so blogging here at my company blog, I decided that it was time for me to set up my own. I still very much work for EMC Consulting, it’s just that recently I’ve started to get involved in more community and OSS type things that aren’t always directly relevant to my day job. A lot of what I’ll be talking about in the future will be work that I’m doing outside of that channel.

    I owe the EMC Consulting blogs a lot - thanks to Howard for getting me on here in the first place - I realise that it gave me a bigger voice than I would have had without it’s great reputation and audience.

    If you subscribed to my feed here at http://consultingblogs.emc.com/jamesbroome/default.aspx, then please update your links to the new URL as I’ll be blogging on this site from now on. And, of course, you can still follow me on Twitter at @broomej.

    Expect some exciting news about a new project that will give some context when talking about ASP.NET MVC, S#arp Architecture, Agile development, BDD and all the other good stuff I like, so you can expect some further posts imminently…

  • Turbo-charge your MVC views with Spark and FluentHtml

    If you’ve been following this blog, or those of my colleagues Howard and Jon, it’s probably been obvious that we love the Spark view engine. We’ve been using it in anger for the last 6 months or so on our latest Asp.Net MVC project and between us we have nothing but praise for it.

    I’ve talked before about how the use of Spark really helped us to work better as a team – with .Net developers writing .Net code, and our interface developers writing clean HTML and CSS. Integration of these two parts was simple, with a really terse syntax for adding server side variables and conditional and looping logic without disrupting the markup structure of the view.

    When it comes to creating views for Html forms the MVC Contrib project provides a strongly typed, fluent syntax for writing out Html input elements for your view model in the MvcContrib.FluentHtml library. This removes a lot of the “magic strings” that are found in lot of the MVC examples, and the fluent syntax gives you a convention based approach for the naming of your elements.

    Both these projects remove some of the concerns that were first voiced around MVC – that of “magic strings” and “tag soup” in the view markup. Combining the two together however, results in really slick, terse view code that is strongly typed, convention based and still looks like view markup.

    It’s really easy to tell Asp.Net MVC to use Spark as a view engine – it can be done in one line of code:

    protected void Application_Start(object sender, EventArgs e)
    {
        ViewEngines.Engines.Add(new SparkViewFactory());
    }

    For more information on configuring Spark for your project check out the official documentation.

    It’s equally as easy to use FluentHtml from within Spark. I followed this great post by Tim Scott which details exactly what you need to do. I copied the SparkViewModelPage<T> base class from that post and registered it as my base Spark page type in the same way:

    ViewEngines.Engines.Clear();
    
    var settings = new SparkSettings()
        .SetPageBaseType("MyProject.Web.Views.SparkModelViewPage");
    
    ViewEngines.Engines.Add(new SparkViewFactory(settings));

    That’s pretty much all you need to do. You can now access the FluentHtml API from within the view code easily from the helper exposed through the base class.

    Here’s some example view code for an Html form for a Worker entity:

    <viewdata model="MyProject.Web.Controllers.Organization.WorkersController.WorkerFormViewModel" />
    
    <form method="post">
    
        !{Html.AntiForgeryToken()}
        !{this.Hidden(x => x.Worker.Id)}
    
        <fieldset>
    
                <div>
                    !{this.TextBox(x => x.Worker.FirstName).Label("First Name")}
                    !{this.ValidationMessage(x => x.Worker.FirstName)}
                </div>
    
                <div>
                    !{this.TextBox(x => x.Worker.LastName).Label("Last Name")}
                    !{this.ValidationMessage(x => x.Worker.LastName)}
                </div>
    
                <div>
                    !{this.TextBox(x => x.Worker.BirthDate).Label("Birth Date")}
                    !{this.ValidationMessage(x => x.Worker.BirthDate)}
                </div>
    
                !{this.SubmitButton("Save Worker")}
                !{Html.ActionLink<WorkersController>(c => c.Index(), "Cancel")}
                
        </fieldset>
    
    </form>

    Which results in the following Html code being rendered:

    <form method="post">
    
        <input name="__RequestVerificationToken" type="hidden" value="AMQm309UsoQoStclFZgUGSaLVntiux2KO0ce+92aF3hTUurSSzFi7M6Sa6QsEowT" />
        <input id="Worker_Id" name="Worker.Id" type="hidden" value="0" />
    
        <fieldset>
    
                <div>
                    <label for="Worker_FirstName" id="Worker_FirstName_Label">First Name</label>
                    <input id="Worker_FirstName" name="Worker.FirstName" type="text" value="" />
                    
                </div>
    
                <div>
                    <label for="Worker_LastName" id="Worker_LastName_Label">Last Name</label>
                    <input id="Worker_LastName" name="Worker.LastName" type="text" value="" />
                    
                </div>
    
                <div>
                    <label for="Worker_BirthDate" id="Worker_BirthDate_Label">Birth Date</label>
                    <input id="Worker_BirthDate" name="Worker.BirthDate" type="text" value="" />
                    
                </div>
    
                <input id="Save_Worker" name="Save_Worker" type="submit" value="Save Worker" />
                <a href="/Organization/Workers">Cancel</a>
                
        </fieldset>
    
    </form>

    Hopefully this shows very quickly how you can really get slick, terse, strongly typed convention based MVC views by using Spark and FluentHtml together.



    Bookmark and Share
  • Asp.Net MVC Controllers + BDD = The perfect match? Part 3: The AccountController contd.

    This is part 3 in a series of posts on using Behaviour Driven Development to build and test your MVC controllers. The full series is as follows:

     

    In part one I defined a convention for how I was going to test my MVC controller functionality using JP Boodhoo’s developwithpassion library and in part two I took this a step further by building out some real specifications for the functionality that the out-the-box ASP.Net MVC AccountController provides. I dealt with the log on and log off functionality, which leaves us with the following requirements:

    • Register a new User
    • Change a User’s password
    • Prevent Window’s authenticated Users from accessing the application

     

    Registering a new user

    Registering a new user follows a similar pattern to the log on functionality. The user needs to be able to browse to the registration view and then submit their new user data to register a new account.

    1. The first specification deals with being able to browse (HTTP GET request) to the register view. There is some added complexity in this specification, as the minimum password length value (used for validation purposes) is being retrieved from the membership service (remember I’m building these specifications backwards from the out-the-box functionality). In order to prove that this is happening as expected, I’m able to set up an expectation on my mock membership service that returns a value of 4, prove that the service was in fact called using the RhinoMocks VerifyAllExpectations() method and that the value is passed to the view by testing the value in the ViewData property bag. So far, so good.

    My specification for displaying the register view is as follows:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_display_the_register_view : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            membership_service.Expect(ms => ms.MinPasswordLength).Return(4);
    
        because b = () =>
            result = sut.Register();
    
        it should_display_the_register_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_retreive_the_minimum_password_length_from_the_membership_service = () =>
            membership_service.VerifyAllExpectations();
    
        it should_display_the_minimum_password_length_in_the_view = () =>
            result.is_a_view_and().ViewData["PasswordLength"].should_be_equal_to(4);
    }

    2. As with the Log on specifications, I then test the “happy day” scenario for registering a new user. When everything goes to plan we should create the new user, log the user on to the system and redirect them back to the home page. Again, we can set up the mock membership service to return a successful registration status when we call it:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_register_a_user : concern_for_account_controller
    {
        static ActionResult result;
        static MembershipCreateStatus success;
    
        context c = () =>
        {
            success = MembershipCreateStatus.Success;
            membership_service.Stub(ms => ms.CreateUser(user_name, password, email)).Return(success);
        };
    
        because b = () =>
            result = sut.Register(user_name, email, password, confirm_password);
    
        it should_create_the_user = () =>
            membership_service.was_told_to(ms => ms.CreateUser(user_name, password, email));
    
        it should_log_the_user_on_the_sytem = () =>
            forms_authentication.was_told_to(fa => fa.SignIn(user_name, false));
    
        it should_redirect_the_user_to_the_home_page = () =>
        {
            result.is_a_redirect_to_route_and().controller_name().should_be_equal_to("Home");
            result.is_a_redirect_to_route_and().action_name().should_be_equal_to("Index");
        };
    }

    3. Now we need to test the error cases. To register a new user, we need to specify a user name, email address, password and password again. We can simulate an invalid state for each scenario to prove that the controller handles the invalid input and responds accordingly. First, the user name:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_register_a_user_with_no_username : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            user_name = string.Empty;
    
        because b = () =>
            result = sut.Register(user_name, email, password, confirm_password);
    
        it should_display_the_register_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_username_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["username"].should_not_be_null();
    }

    4. And then the same for email address:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_register_a_user_with_no_email : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            email = string.Empty;
    
        because b = () =>
            result = sut.Register(user_name, email, password, confirm_password);
    
        it should_display_the_register_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_email_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["email"].should_not_be_null();
    }

    5. Then an invalid password:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_register_a_user_with_an_invalid_password : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            password = string.Empty;
    
        because b = () =>
            result = sut.Register(user_name, email, password, confirm_password);
    
        it should_display_the_register_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_password_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["password"].should_not_be_null();
    }

    6. And then when the two passwords don’t match:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_register_a_user_with_password_that_dont_match : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            confirm_password = "different";
    
        because b = () =>
            result = sut.Register(user_name, email, password, confirm_password);
    
        it should_display_the_register_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_password_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["_FORM"].should_not_be_null();
    }

    7. Finally, all the values may be ok, but the membership service may not let us register the user e.g. if the username already exists. In this case, we can simulate the membership service returning a failure response and check the desired behaviour:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_register_a_user_and_the_user_cant_be_created : concern_for_account_controller
    {
        static ActionResult result;
        static MembershipCreateStatus failed;
    
        context c = () =>
        {
            failed = MembershipCreateStatus.ProviderError;
            membership_service.Stub(ms => ms.CreateUser(user_name, password, email)).Return(failed);
        };
    
        because b = () =>
            result = sut.Register(user_name, email, password, confirm_password);
    
        it should_try_to_create_the_user = () =>
            membership_service.was_told_to(ms => ms.CreateUser(user_name, password, email));
    
        it should_display_the_register_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["_FORM"].should_not_be_null();
    }

     

    Change password

    Changing a user’s password also follows a similar pattern – a user can browse to the change password view and then submit their new password details. My specifications follow the same pattern as before:

    1. Check the correct view is returned when the user browses to the change password url

    2. Test the happy day scenario when the user submits their data

    3. Test the error case scenarios when the user submits invalid data

    1. The specification for retrieving the change password view is similar to the one for the registration view:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_display_the_change_password_view : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            membership_service.Expect(ms => ms.MinPasswordLength).Return(4);
    
        because b = () =>
            result = sut.ChangePassword();
    
        it should_display_the_change_password_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_retreive_the_minimum_password_length_from_the_membership_service = () =>
            membership_service.VerifyAllExpectations();
    
        it should_display_the_minimum_password_length_in_the_view = () =>
            result.is_a_view_and().ViewData["PasswordLength"].should_be_equal_to(4);
    }

    2. The “happy day” scenario is slightly more complicated. In order to change the user’s password, the Account Controller needs to access the current user, which in the out-the-box functionality it does by just accessing the User property of the controller.

    if (MembershipService.ChangePassword(User.Identity.Name, currentPassword, newPassword))
    {
        return RedirectToAction("ChangePasswordSuccess");
    }

    This returns the IPrincipal associated with the current HTTP context, which means we need to simulate this in our specification. Faking an HTTP context is notoriously difficult to test, made slightly easier with the System.Web.Abstractions namespace. I’d prefer not to have any dependency on HttpContext in my controllers – which can be achieved by using ActionFilters – a technique that I describe in an earlier blog post.

    However, the developwithpassion BDD framework helps us out on this one by providing an easy way to add further set up logic after we create the system under test. In this scenario we need to set up a mock HttpContext, assign a mock user and add it all to the AccountController’s ControllerContext.

    Taking all this into account, our specification looks like this:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_change_a_users_password : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            membership_service.Stub(ms => ms.ChangePassword(user_name, password, new_password)).Return(true);
    
        after_the_sut_has_been_created set_up_the_current_user = () =>
        {
            sut.ControllerContext = new ControllerContext();
            sut.ControllerContext.HttpContext = an<HttpContextBase>();
            sut.ControllerContext.HttpContext.User = an<IPrincipal>();
            sut.ControllerContext.HttpContext.User.Stub(x => x.Identity).Return(an<IIdentity>());
            sut.ControllerContext.HttpContext.User.Identity.Stub(x => x.Name).Return(user_name);
        };
    
        because b = () =>
            result = sut.ChangePassword(password, new_password, confirm_new_password);
    
        it should_change_the_users_password = () =>
            membership_service.was_told_to(ms => ms.ChangePassword(user_name, password, new_password));
    
        it should_redirect_the_user_to_the_change_password_success_view = () =>
            result.is_a_redirect_to_route_and().action_name().should_be_equal_to("ChangePasswordSuccess");
    }

    3. The error case scenarios are then as before. Whenever I need to access the User property of the ControllerContext, I need to set it up in as above:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_change_a_users_password_with_no_current_password : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            password = string.Empty;
    
        because b = () =>
            result = sut.ChangePassword(password, new_password, confirm_new_password);
    
        it should_display_the_change_password_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_password_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["currentPassword"].should_not_be_null();
    }
    
    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_change_a_users_password_with_an_invalid_new_password : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            new_password = string.Empty;
    
        because b = () =>
            result = sut.ChangePassword(password, new_password, confirm_new_password);
    
        it should_display_the_change_password_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_password_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["newPassword"].should_not_be_null();
    }
    
    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_change_a_users_password_with_passwords_that_dont_match : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            confirm_new_password = "different";
    
        because b = () =>
            result = sut.ChangePassword(password, new_password, confirm_new_password);
    
        it should_display_the_change_password_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["_FORM"].should_not_be_null();
    }
    
    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_change_a_users_password_and_the_password_cant_be_changed : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            membership_service.Stub(ms => ms.ChangePassword(user_name, password, new_password)).Return(false);
    
        after_the_sut_has_been_created set_up_the_current_user = () =>
        {
            sut.ControllerContext = new ControllerContext();
            sut.ControllerContext.HttpContext = an<HttpContextBase>();
            sut.ControllerContext.HttpContext.User = an<IPrincipal>();
            sut.ControllerContext.HttpContext.User.Stub(x => x.Identity).Return(an<IIdentity>());
            sut.ControllerContext.HttpContext.User.Identity.Stub(x => x.Name).Return(user_name);
        };
    
        because b = () =>
            result = sut.ChangePassword(password, new_password, confirm_new_password);
    
        it should_try_to_change_the_users_password = () =>
            membership_service.was_told_to(ms => ms.ChangePassword(user_name, password, new_password));
    
        it should_display_the_change_password_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["_FORM"].should_not_be_null();
    }
    
    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_change_a_users_password_and_an_error_occurs : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            membership_service.Stub(ms => ms.ChangePassword(user_name, password, new_password)).Throw(new Exception());
    
        after_the_sut_has_been_created set_up_the_current_user = () =>
        {
            sut.ControllerContext = new ControllerContext();
            sut.ControllerContext.HttpContext = an<HttpContextBase>();
            sut.ControllerContext.HttpContext.User = an<IPrincipal>();
            sut.ControllerContext.HttpContext.User.Stub(x => x.Identity).Return(an<IIdentity>());
            sut.ControllerContext.HttpContext.User.Identity.Stub(x => x.Name).Return(user_name);
        };
    
        because b = () =>
            result = sut.ChangePassword(password, new_password, confirm_new_password);
    
        it should_try_to_change_the_users_password = () =>
            membership_service.was_told_to(ms => ms.ChangePassword(user_name, password, new_password));
    
        it should_display_the_change_password_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_validation_errors_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["_FORM"].should_not_be_null();
    }

    4. Finally, when a password is successfully changed, the user is redirected to the “change password success” view. We have already tested that the redirection occurs in the “happy day” specification, so all that’s left is to prove that we can actually access that view:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_display_the_change_password_success_view : concern_for_account_controller
    {
        static ActionResult result;
    
        because b = () =>
            result = sut.ChangePasswordSuccess();
    
        it should_display_the_change_password_success_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    }

     

    Preventing Windows Authentication

    The last thing which the out-the-box AccountController does for us, is deny access to users who are authenticated using Windows authentication. It does this by overriding the OnActionExecuting method (which will fire before any action method executes) and throws an exception if the current user is a WindowsIdentity:

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity is WindowsIdentity)
        {
            throw new InvalidOperationException("Windows authentication is not supported.");
        }
    }

    Fortunately, this can easily be tested as each controller inherits the IActionFilter interface. As long as we cast our AccountController as an IActionFilter first, we can test this overridden method:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_do_something_and_the_current_user_is_authenticated_using_windows : concern_for_account_controller
    {
        static ActionExecutingContext filter_context;
        static InvalidOperationException invalid_operation_exception;
    
        context c = () =>
        {
            filter_context = new ActionExecutingContext();
            filter_context.HttpContext = an<HttpContextBase>();
            filter_context.HttpContext.User = an<IPrincipal>();
            filter_context.HttpContext.User.Stub(x => x.Identity).Return(WindowsIdentity.GetAnonymous());
        };
    
        because b = () =>
        {
            try
            {
                ((IActionFilter)sut).OnActionExecuting(filter_context);
            }
            catch (InvalidOperationException ive)
            {
                invalid_operation_exception = ive;
            }
        };
    
        it should_throw_an_invalid_operation_exception = () =>
            invalid_operation_exception.should_not_be_null();
    }

     

    Summary

    So I’ve now got a full set of executable specifications for the out-the-box AccountController. Although for these examples I’ve worked backwards from the functionality to the specifications, hopefully this provides an insight into how I would then go about building the functionality for new controllers in my application, or modifying/extending this existing functionality. The real benefit of BDD is that my specifications are easy to read and understand and describe the desired behaviour of the system, especially when running them through the specification parser, which gives me the following HTML output:

     

    SpecReport2 

     

    The process of writing these specifications for the AccountController has also highlighted that the AccountController is doing too much work around validation. In my opinion, the AccountController should pass off the validation responsibility to something else in order to keep the controller logic clean. Therefore, if the validation rules change, the AccountController behaviour does not need to. Behaviour Driven development helps with this process of deciding what the actual responsibility of a class really is. If you find you’re having to write too many specifications for a particular SUT, then maybe it’s doing too much. Single responsibility principle states that each class should have one responsibility – in the case of the controller this is governing the flow of the application. If the controller could delegate the validation to something else then it’s specifications and behaviour would be much simpler and your application less brittle.

    In the final post I’ll provide the full source code for these examples and detail how then can be executed.

     

    Bookmark and Share
  • The importance of conventions – from Asp.Net MVC to a successful project team

    My colleague Jon George has recently been posting about his experiences of performance tuning our latest web application, built on Asp.Net MVC. His introductory post talks briefly about how we spent a large effort in laying the correct foundations for the project, which have ultimately led to its success. Being the “technical lead who had inconsiderately booked his wedding and an extended honeymoon right in the middle of the project”, I was obviously keen to ensure that that project didn’t fall down in a big heap whilst I was away. Although Jon would have you believe otherwise, my wedding and subsequent absence was actually planned well before we embarked on this project, so I knew from the offset that we had a risk around handover and consistency of delivery during project’s lifetime. To add to this, this was my first “official” Dev Lead role for EMC Consulting so I wanted to make sure that we got things right from the offset.

    Howard and I started planning and brainstorming how we were going to approach this project well before sprint zero. We were lucky to have few technical restrictions, but the side effect of this was that we had a vast amount of decisions to make, with a vast number of options for each choice. We decided right from the offset that we were going to use Asp.Net MVC. We both have a background in web development, before .Net and Webforms, so moving back to a more “webby” web framework was something that we were really keen to do. We’d also hit a lot of pain-points in previous projects with Webforms and we were hoping MVC would allow us to get round these and do things the way we wanted to. MVC Version 1.0 had literally just been released, so we were good to go.

    One of the main benefits mentioned when discussing Asp.Net MVC is the use of convention over configuration – a design principle that aims to reduce the number of decisions that developers need to make. The result of this is consistency, less code and an overall decrease in development time.

    For example, in the MVC framework all controller classes are named with the suffix “controller”. So, if you have a controller responsible for search functionality, you know you need a SearchController.

    Removing a decision needed to be made by a developer (in this case, what to call a controller class), albeit on a minute scale, adds up when when you apply it time and time again over lots of different conventions throughout the lifetime of a project. Asp.Net MVC does not enforce these conventions by any means, and practically everything is overridable, customisable or configurable – but each time you break from a convention, you’re adding time, complexity and inconsistency to your project solution. In short, if you follow the conventions, things are quick, easy and consistent. Happy days.

    A lot of the communities around Asp.Net MVC have adopted this love of conventions too. We built our site around Billy McCafferty’s excellent Sharp Architecture, which is a “architectural reference for a best practice Asp.Net MVC web application” i.e. it defined the conventions on what we needed in an MVC solution, were everything would live and how it would all talk to each other. This, in turn is built upon James Gregory’s Fluent NHibernate – a project solely concerned with defining a convention based approach to using NHibernate, in order to eliminate the need for manually editing XML mapping files. Like I say, conventions at a minute scale all add up to save time, remove decisions and increase consistency within a solution.

    The suprising thing was however, over the course of the project, this convention based approach extended out of the MVC solution and started to permeate other parts of the project and the team. We’d set a firm foundation of how we were going to build the code, but we had also been setting firm foundations of how the project was going to run.

    As Jon mentioned, I’m a big fan of Getting Real and set out from the beginning with it’s principles in mind. We had a fixed budget and a fixed delivery date, so the scope of what we were delivering had to be the thing that moved. We were really cutthroat in determining what was “core” functionality for our site to launch. This was drilled into everyone who got involved with the team over the course of the project in order to eliminate scope creep from all angles. “We are only building core functionality” became my mantra and resulted in a convention that everyone understood, which was to say no to any new feature requests. If the client pushed, then they were added to the end of the backlog, well away from the core items that were to be developed first.

    We were told to “spend the money as if it were our own”. We adopted this mantra right from sprint zero, evaluating and spiking a multitude of open source technology which we baked into our solution from the beginning. This convention of challenging every cost enabled us to validate and prioritise our requirements. “What's the added business value?” is a question that would be asked a lot if the team thought we were being asked to develop something they thought was giving little benefit. Being able to challenge functionality allowed us to really concentrate on our core features – which ultimately lead to us delivering the project ahead of schedule.

    I set a rule in the first sprint that every team member would demo to the client at the end of every sprint. Whilst sprint demos are not a new thing to most people here, not everyone always gets the chance to demo their work, for various reasons – team size, time constraints, client involvement etc. I wanted to instil a convention right from the beginning that everyone in the team would demo what they had done during the sprint. So, we had designers demoing new creative work, developers demoing functionality, testers talking about bug counts, cross browser issues and running automated UI tests, database developers demoing BI and ETL processes. Whilst not all of this interests everybody, there was never any question of whether someone would be required to “show and tell” what they’d been up to. The result of this was that we never wasted time during a sprint discussing who would demo what and everyone made damn sure that what they were doing worked by the end of the sprint.

    The combined effect of all these conventions is that everyone on our core project team is able to explain “this is how we do things on this project and these are the reasons why”. That’s a powerful message. One of the main benefits of working in a consultancy is that we have experts in a long list of specialities and whilst those skills are not needed full time for a project, its great to be able to draw on that experience as and when required. We had a core team of less than 15 people, yet over the lifetime of the project, over 30 of our consultants had provided direct input into the end result. Without embedding, understanding and enforcing our project’s conventions within the core team, this could have been messy business.

    So, what’s the point in all this? Well, as Jon stated, I “abandoned” the project right in the middle to take a 6 week honeymoon. (pause for memories of sun, sand and… well, you get the idea). I was confident when I left that the project was in safe hands – we already had a great team and Jon is a great Dev Lead himself. But I don’t think I realised just how well everything was going to go. We had a brief handover where we discussed loosely how I thought features were going to pan out and left it at that. I returned after 6 weeks to find that

    • The project kept momentum and had considerably moved forward in terms of functionality
    • The features we had discussed had been developed in the way that we talked about - with no issues 
    • Jon had quickly engaged and developed a relationship with the client as he understood the solution and how we were running the project
    • Everyone had been demoing their feature-complete work at the end of every sprint
    • No new features had been added to the backlog
    • I was able to easily pick up the solution where I left off and continue to work on the new features that had been developed
    • The client was still happy!

    The project didn’t fall down in a big heap whilst I was away, in fact it carried on at the same pace, quality and direction that it had before I left. That could actually say something about me! Or probably more about Jon! But I think most of all it says that if you spend time getting your conventions right then a lot of things will just fall into place. And that makes for a smooth running project.



    Bookmark and Share
  • Asp.Net MVC Controllers + BDD = The perfect match? (Part 2: Log On and Log Off with the AccountController)

    This is part 2 in a series of posts on using Behaviour Driven Development to build and test your MVC controllers. The full series is as follows:

     

    In my last post I talked about why I thought that BDD was a great choice when it comes to testing your MVC controllers. The controllers in an MVC application are what handle the user actions and inputs and determine what the correct result should be e.g. displaying a view or redirecting to another action. The controllers are therefore what govern the flow of your application from the end user’s perspective, which makes them ideal candidates for BDD style specifications as the language and business requirements are relevant to and can be validated by a non-technical team member (e.g. the Product Owner).

    I began by looking at the out-the-box Asp.Net MVC application that you get when you select “File | New Project | ASP.Net MVC Web Application” in Visual Studio as this provides us with some basic, yet widely understood functionality that I can use to illustrate my point. I started by writing specifications for the out-the-box HomeController to prove that it returned the correct views for the Index and About actions, and that the correct data was passed into the ViewData.

    As I mentioned before, this exercise is slightly backwards, as the functionality we are writing specifications for already exists, however, the intention is to show how beneficial BDD can be at this layer of the application and how it could be applied going forward as you build out the rest of your functionality.

     

    Recap

    I’m using JP Boohoo’s developwithpassion BDD library to give me a style and syntax for my BDD specs. If you’re new to BDD, I’d recommend checking out his blog first for some background info on what this library is all about.

    I'd also created some MVC specific extension methods for testing my HomeController so that I can easily prove the type of ActionResult my actions return and check the type-specific properties on them in a fluent syntax e.g.

    it should_return_the_home_view = () =>
        result.is_a_view_and().ViewName.should_be_empty();

     

    The AccountController

    The AccountController is more interesting than the HomeController as it actually does something! If we take a look at the out-the-box functionality it contains, we can see that it provides the following account operations:

    • Log on a User
    • Log off a User
    • Register a new User
    • Change a User’s password
    • Prevent Window’s authenticated Users from accessing the application 

    So, I’ll start in this post by dealing with the Log on and Log off functionality.

     

    Set up

    The out-the-box AccountController provides two constructors, which makes it easy to test. It has two dependencies – a FormsAuthenticationService and a MembershipService, which at runtime will be instantiated using the default forms authenticaiton and membership providers. However, during testing, we can set these to be whatever we want. Our AccountController specifications are all going to use mock versions of these dependencies, which will allow us to set up and simulate the contexts that we need to fulfil our specifications. I start by creating a “base” context that can be used by all my AccountController specifications:

    public abstract class concern_for_account_controller : observations_for_a_sut_without_a_contract<AccountController>
    {
        protected static IFormsAuthentication forms_authentication;
        protected static IMembershipService membership_service;
        protected static string user_name;
        protected static string password;
        protected static bool remember_me;
        protected static string return_url;
        protected static string email;
        protected static string confirm_password;
        protected static string new_password;
        protected static string confirm_new_password;
    
        context c = () =>
        {
            forms_authentication = the_dependency<IFormsAuthentication>();
            membership_service = the_dependency<IMembershipService>();
            membership_service.Stub(ms => ms.MinPasswordLength).Return(4);
            user_name = "name";
            password = "password";
            confirm_password = "password";
            new_password = "newpassword";
            confirm_new_password = "newpassword";
            email = "email";
            remember_me = false;
            return_url = "/";
        };
    }

     

    The developwithpassion BDD library will take care of a lot of set up work for us. I initialise the IFormsAuthentication and IMembershipService using the the_depdendency() method, which tells the BDD library to create a new mock version of each of these interaces using RhinoMocks, and also to use them in the constructor of the system under test (in this case, the AccountController). So, whenever I access the system under test in one of my specifications, it will already be created and have these mock instances as the dependencies that the AccountController needs.

     

    Log On

    This first set of specifications I created covers the two LogOn actions. The first is a GET request action which simply displays the Log On view. The second only accepts POST requests and performs the actual log on, providing everything is valid. Here’s the out-the-box functionality that we’re going to be testing:

    public ActionResult LogOn()
    {
    
        return View();
    }
    
    [AcceptVerbs(HttpVerbs.Post)]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
        Justification = "Needs to take same parameter type as Controller.Redirect()")]
    public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
    {
    
        if (!ValidateLogOn(userName, password))
        {
            return View();
        }
    
        FormsAuth.SignIn(userName, rememberMe);
        if (!String.IsNullOrEmpty(returnUrl))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Home");
        }
    }

    Remember – this is the out-the-box Asp.Net MVC functionality that we get with a new project. Working backwards from this functionality, I came up with the following set of specifications…

     

    1. The first action (for a GET request) is pretty simple – we’re just proving that the return is a ViewResult and that the view name is the same as the action name (in this case “LogOn”) by relying on the convention over configuration approach of Asp.Net MVC. If we don’t supply a specific view name for a view result, then the framework will look for one with the same name as the action.

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_display_the_log_on_view : concern_for_account_controller
    {
        static ActionResult result;
    
        because b = () =>
            result = sut.LogOn();
    
        it should_display_the_log_on_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    }

     

    2. We then need to test the “happy day” scenario. What happens when everything goes as expected? In this case, we validate the user successfully, log the user on successfully and redirect to where they came from. We can override the base context and tell the membership service that we we ask it to validate the user it will return a successful response.

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_log_on_a_user : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            membership_service.Stub(ms => ms.ValidateUser(user_name, password)).Return(true);
    
        because b = () =>
            result = sut.LogOn(user_name, password, remember_me, return_url);
    
        it should_validate_the_users_credentials = () =>
            membership_service.was_told_to(ms => ms.ValidateUser(user_name, password));
    
        it should_log_the_user_on_to_the_system = () =>
            forms_authentication.was_told_to(fa => fa.SignIn(user_name, remember_me));
    
        it should_redirect_the_user_back_to_where_they_came_from = () =>
            result.is_a_redirect_and().Url.should_be_equal_to(return_url);
    }

     

    3. Next, we can change the context slightly, this time to blank out the return url. This simulates the user logging on without browsing any other part of the site first. In this case, we validate and authenticate the user in the same way, but we redirect to the home page.

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_log_on_a_user_and_they_havent_come_from_anywhere : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
        {
            return_url = string.Empty;
            membership_service.Stub(ms => ms.ValidateUser(user_name, password)).Return(true);
        };
    
        because b = () =>
            result = sut.LogOn(user_name, password, remember_me, return_url);
    
        it should_validate_the_users_credentials = () =>
            membership_service.was_told_to(ms => ms.ValidateUser(user_name, password));
    
        it should_log_the_user_on_to_the_system = () =>
            forms_authentication.was_told_to(fa => fa.SignIn(user_name, remember_me));
    
        it should_redirect_the_user_to_the_home_page = () =>
        {
            result.is_a_redirect_to_route_and().controller_name().should_be_equal_to("Home");
            result.is_a_redirect_to_route_and().action_name().should_be_equal_to("Index");
        };
    }

     

    4. Then we need to start checking our error case scenarios – what happens if we try to log on without specifying a username?

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_log_on_a_user_with_no_username : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            user_name = string.Empty;
    
        because b = () =>
            result = sut.LogOn(user_name, password, remember_me, return_url);
    
        it should_display_the_log_on_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_username_required_validation_message_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["username"].should_not_be_null();
    }

     

    5. And the same for password:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_log_on_a_user_with_no_password : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            password = string.Empty;
    
        because b = () =>
            result = sut.LogOn(user_name, password, remember_me, return_url);
    
        it should_display_the_log_on_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_password_required_validation_message_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["password"].should_not_be_null();
    }

     

    6. If the user does supply a username and password then we need to try to validate it via the membership service. The credentials they’ve supplied may be invalid, which we can simulate by stubbing out the response from the membership service:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_log_on_a_user_who_does_not_exist : concern_for_account_controller
    {
        static ActionResult result;
    
        context c = () =>
            membership_service.Stub(ms => ms.ValidateUser(user_name, password)).Return(false);
    
        because b = () =>
            result = sut.LogOn(user_name, password, remember_me, return_url);
    
        it should_try_to_validate_the_users_credentials = () =>
            membership_service.was_told_to(ms => ms.ValidateUser(user_name, password));
    
        it should_display_the_log_on_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_invalid_username_validation_message_in_the_view = () =>
            result.is_a_view_and().ViewData.ModelState["_FORM"].should_not_be_null();
    }

     

    Log off

    7. Finally, for completeness, we can test the expected behaviour for logging off a user, which tells the authentication to sign the user out and then redirects back to the home page:

    [Concern(typeof(AccountController))]
    public class when_the_account_controller_is_told_to_log_off_a_user : concern_for_account_controller
    {
        static ActionResult result;
    
        because b = () =>
            result = sut.LogOff();
    
        it should_log_the_user_out_of_to_the_system = () =>
            forms_authentication.was_told_to(fa => fa.SignOut());
    
        it should_redirect_the_user_to_the_home_page = () =>
        {
            result.is_a_redirect_to_route_and().controller_name().should_be_equal_to("Home");
            result.is_a_redirect_to_route_and().action_name().should_be_equal_to("Index");
        };
    }

     

    Output

    If I run my specifications through the Gallio Icarus test runner I can see that they are being executed successfully:

    GallioResults 

    But more interestingly, I can use JP’s bdddoc report generator to produce an easy to read, BDD specification report based on my specifications in code:

     SpecReport

     

    Summary

    This is where the real benefit of BDD comes in. My specifications in code are understandable and easily readable when ran through a simple report parser. They can be discussed and validated by developers and non-developers alike. I could show this to the guys behind Asp.Net MVC and see if I’ve understood their desired behaviour of the out-the-box AccountController! If not, we figure out what’s wrong or missing and carry on. At this level of the application the specs really add value in the context of the business requirements of your system. This is why I think that BDD is a great technique for testing the controllers of your MVC application.


    In the next post I’ll look at the remaining functionality in the AccountController. I’ll be posting a full working code sample of these specs at the end of the series.

     

    Bookmark and Share
  • Asp.Net MVC Controllers + BDD = The perfect match? [Part #1: The HomeController]

    This is part 1 in a series of posts on using Behaviour Driven Development to build and test your MVC controllers. The full series is as follows:

     

    Behaviour Driven Development/Design has been gaining a lot of traction recently amongst the community and whilst not everyone may be using it in anger to write code and deliver projects, most people should have a fair idea of what it is all about by now. I’ve been talking about it for a while, since I attended JP Boodhoo’s Nothin But .Net course over a year ago, where I was exposed to BDD for the first time. For the last 6 months or so, I’ve been Dev Lead on a greenfield e-commerce application, using Asp.Net MVC, Sharp Archictecture, N2 CMS, NHibernate, Spark View Engine, Post Sharp and a whole host of other cool stuff. However the main thing for me has been that it has been the first project where I’ve been able to use BDD properly, the result of which is that we’ve written more tests that any other project I’ve been on and because of that the quality of the code we’re producing is getting higher and higher each sprint.

    BDD has a real sweet spot when it’s used to describe high level, user story-like business specifications. With MVC, this can be used to great effect when building out the controllers layer of your application. The controllers are what handle user actions and inputs to the application, determining what the correct result should be e.g. displaying a view, redirecting to another action. In a nutshell the controllers are what govern the flow of your application from the end users perspective, which makes them ideal candidates for BDD style specifications.

    The out-of-the-box Asp.Net MVC project (File | New Project) comes with some pre-built controller functionality – the HomeController and the AccountController. This allows you to build a MVC application with user authentication very quickly and, although most people will choose not to use this code for anything other than a simple web app, it provides a set a business rules and functionality that everyone is familiar with.

    So, to illustrate my point, I decided to use BDD to create a series of specifications for the out-the-box HomeController and AccountControlller functionality. Whilst this is a slightly backwards excercise as the functionality for these controllers already exists, hopefully this will show how you could continue in this way to build up the other controllers in your application.

     

    Pre-Requisites

    We’ve been using JP Boodhoo’s style of BDD specifications on my current project and whilst this has proved successful, during this time, JP has been adapting and pushing his style and syntax to something even more terse and fluent. He now has the developwithpassion library available up on GitHub which I’ve used for this excercise. It’s been a bit of a jump from the style and syntax that I’ve been using on my project, but I’m really happy with the results. I’ll post a fully working code sample at the end of the series with everything you need to run the specs.

     

    First up – the HomeController.

    If we imagine that the HomeController did not already exist, our first requirement would be that we needed something to handle the overall default action on the site – i.e. what happens when someone just browses to http://mysite.com ? We now know that we need a HomeController and that it’s default action should be to display the home page of the site. We also know (because it already exists) that our home page view should display a message – “Welcome to ASP.NET MVC!”.

    So, our first scenario is:

    When the home controller is told to display the default view

    • It should display the home page view
    • It should display the welcome message in the view

    Translating this into code, I came up with the following specification

    [Concern(typeof (HomeController))]
    public class when_the_home_controller_is_told_to_display_the_default_view : observations_for_a_sut_without_a_contract<HomeController>
    {
        static string key;
        static string message;
        static ActionResult result;
    
        context c = () =>
        {
            key = "Message";
            message = "Welcome to ASP.NET MVC!";
        };
    
        because b = () =>
            result = sut.Index();
    
        it should_return_the_home_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    
        it should_display_the_welcome_message_in_the_view = () =>
            result.is_a_view_and().ViewData[key].should_be_equal_to(message);
    }

    The fluent syntax in the BDD specifications is mostly straight from JP’s developwithpassion library, which uses extension methods to the extreme to wrap MbUnit and RhinoMocks. I added a couple of MVC ActionResult specific extension methods to help with checking the results of the actions by casting them to their expected types first:

    public static class ActionResultExtensions
    {
        public static ViewResult is_a_view_and(this ActionResult result)
        {
            return (result as ViewResult);
        }
    
        public static RedirectResult is_a_redirect_and(this ActionResult result)
        {
            return (result as RedirectResult);
        }
    
        public static RedirectToRouteResult is_a_redirect_to_route_and(this ActionResult result)
        {
            return (result as RedirectToRouteResult);
        }
    
        public static string controller_name(this RedirectToRouteResult redirect_result)
        {
            return redirect_result.RouteValues["Controller"].ToString();
        }
    
        public static string action_name(this RedirectToRouteResult redirect_result)
        {
            return redirect_result.RouteValues["Action"].ToString();
        }
    
        public static void should_be_empty(this String the_string)
        {
            the_string.should_be_equal_to(string.Empty);
        }
    }

    I’m also relying on the convention over configuration approach of MVC in that if you don’t pass in a view name to an ActionResult then it will use the name of the calling action, so when I say:

    it should_return_the_home_view = () =>
        result.is_a_view_and().ViewName.should_be_empty();

    I’m enforcing that the view name is the same as the action name.

    We’ve now got the default action of the HomeController covered and if these specifications were executed, they would pass based on the out-the-box MVC project HomeController functionality:

    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";
    
            return View();
        }
    
        public ActionResult About()
        {
            return View();
        }
    }

    Our second scenario (which we know by looking at what the HomeController already does!) is that we need an about page. We (already) decided to handle this by adding an About action to the HomeController.

    When the home controller is told to display the about view

    • It should display the about page view

    Simple really. Try to remember that normally, the HomeController would not already have this functionality so we would be driving this out from the spec. Translating this into code and following the conventions I had previously I came up with the following specification:

    [Concern(typeof(HomeController))]
    public class when_the_home_controller_is_told_to_display_the_about_view : observations_for_a_sut_without_a_contract<HomeController>
    {
        static ActionResult result;
    
        because b = () =>
            result = sut.About();
    
        it should_return_the_about_view = () =>
            result.is_a_view_and().ViewName.should_be_empty();
    }

    Ok, so this isn’t rocket science, and the HomeController doesn’t really do much, but if we wanted to add a help page for example then we could go on in similar fashion for adding the spec and then adding the action onto the HomeController. Or, if we decided to change the default home page view (e.g. to display the current date, or the logged in username, or a different view for every day of the week), then we can add to or modify our HomeController specifications accordingly.

     

    Next Time…

    I’m really happy with these controller specs and creating them for the HomeController, although simple, has given me a style and convention of how I’m going to approach the other functionality in our out-the-box MVC application. In the next post, I’ll start to look at the AccountController, where things get a bit more interesting. Hopefully this has shown how powerful BDD can be when talking at the controller level of an application.

    UPDATE - Due to wierd formatting issues with the code snippets, I'd recommend reading this in Chrome, which seems to give the best experience!

    @broomej

     

    Bookmark and Share
  • Asp.Net MVC – Using ActionFilters to remove HttpContext from your controllers

     

    One of the benefits of Asp.Net MVC is that it allows you to write easily testable code. One thing that has always been notoriously difficult to test is the HttpContext object and its associated values – the Request and Response etc. This is why I didn’t like it when dependencies on HttpContext started to creep into our Controller actions, as it meant that our Controllers became harder to test. Having to set up mock HttpContexts for each set of controller tests started to get annoying and any barrier to writing tests is a bad thing in my book – especially as we’d spent a real effort on my current project establishing BDD amongst the team.

    One of the ways in which this can be avoided is to use the built in ActionFilters in Asp.Net as a kind of cheap AOP – attributing your actions with filters that will “inject” the necessary values into your action’s parameters at runtime. This means your action can be changed to just accepting the values it needs as method parameters, allowing you to test them really easily.

    Here’s a simple example:

    public ActionResult GetHttpReferrer()
    {
        ViewData.Add("urlReferrer", 
            ControllerContext.HttpContext
    .Request.UrlReferrer.ToString()); return View(); }

    This action just displays a view containing the UrlReferrer string. It has to access the HttpContext via the ControllerContext, which means that in order to test this action we would need to set up a mock or fake HttpContext with a mock or fake Request object and add them to the ControllerContext before we can test the action. This is fine if we’re doing this once, but chances are that another action or another controller will need to do a similar thing.

     

    Enter the ActionFilter.

    To remove the dependeny on HttpContext in the controller action, we can create an ActionFilter that provides the action with this value at runtime. Here’s a simple ActionFilter that adds the url referrer string to the action parameters:

    using System.Web.Mvc;
    
    public class HttpReferrerAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting
            (ActionExecutingContext filterContext)
        {
            filterContext.ActionParameters["urlReferrer"] = 
                filterContext.HttpContext.Request.UrlReferrer.ToString();
        }
    }

    All we need to do is override the OnActionExecuting() method, which will get called before the action gets called. At this point we can access the HttpContext and add the value we need into the action’s collection of parameters, which the ActionFilter knows about.

    We can write tests for this ActionFilter by creating a fake or mock HttpContext and adding it to the ActionExecutingContext that gets passed in to the OnActionExecuting method(). Whilst this is the same as having to set up the dependencies for the controller tests, the point is that we only have to do this once for this ActionFilter, which can then be re-used amongst controllers. It keeps the controllers free of dependencies on HttpContext and makes the code cleaner and more maintainable.

    I use JP Boohoo’s style of BDD specifications for testing, which is basically a set of extension methods that add syntactic sugar to your test code. My specification for the HttpReferrerAttribute is as follows:

    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.Mvc;
    using SpecHelpers;
    using Observation = MbUnit.Framework.TestAttribute;
    
    public class when_the_http_referrer_attribute_is_told_to_execute 
    : ContextSpecification<HttpReferrerAttribute> { private ActionExecutingContext filter_context; private HttpContextBase http_context; private HttpRequestBase request; private Uri url_referrer; protected override HttpReferrerAttribute create_sut() { return new HttpReferrerAttribute(); } protected override void establish_context() { url_referrer = new Uri("http://thelastplaceicamefrom.com"); filter_context = new ActionExecutingContext(); filter_context.ActionParameters =
    new Dictionary<string, object>(); filter_context.ActionParameters.Add("urlReferrer", null); request = dependency<HttpRequestBase>(); http_context = dependency<HttpContextBase>(); request.setup_result(r => r.UrlReferrer)
    .Return(url_referrer); http_context.setup_result(c => c.Request)
    .Return(request); filter_context.HttpContext = http_context; sut = create_sut(); } protected override void because() { sut.OnActionExecuting(filter_context); } [Observation] public void should_set_the_url_referrer_parameter_correctly() { filter_context
    .ActionParameters["urlReferrer"]
    .should_be_equal_to(url_referrer.ToString()); } }

    A few things to note here – the dependency<>() extension method is just wrapping a call to RhinoMocks to create a mock object that we’re using in the test:

    protected virtual InterfaceType dependency<InterfaceType>() 
    where InterfaceType :
    class { return MockRepository.GenerateMock<InterfaceType>(); }

    The set_up_result() extension method is setting up a RhinoMocks expectation on the mock object:

    public static IMethodOptions<R> setup_result<T, R>
    (this T mock, Function<T, R> func) where T :
    class { return mock.Expect(func).Repeat.AtLeastOnce(); }

    And the should_be_equal_to() extension method is simply wrapping a call to an MBUnit (or NUnit if you prefer) assert statement:

    public static void should_be_equal_to<T>(this T actual, T expected)
    {
        Assert.AreEqual(expected, actual);
    }

     

    Back to the Action.

    As we have delegated the responsibility of retrieving the url referrer to the ActionFilter, our original controller action now looks like this:

    [HttpReferrer]
    public ActionResult GetHttpReferrer(string urlReferrer)
    {
        ViewData.Add("urlReferrer", urlReferrer);
        return View();
    }

    Which means it can be tested really easily without any dependency on HttpContext. Our full specification for the controller now looks like this:

    using System.Web.Mvc;
    using Filters;
    using SpecHelpers;
    using Observation = MbUnit.Framework.TestAttribute;
    
    public class when_the_home_controller_displays_the_get_referrer_view 
    : ContextSpecification<HomeController> { private string url_referrer; private ActionResult result; protected override HomeController create_sut() { return new HomeController(); } protected override void establish_context() { url_referrer = "http://thelastplaceicamefrom.com"; sut = create_sut(); } protected override void because() { result = sut.GetHttpReferrer(url_referrer); } [Observation] public void should_populate_the_view_with_the_url_referrer() { (result as ViewResult)
    .ViewData["urlReferrer"]
    .should_be_equal_to(url_referrer); } [Observation] public void should_retrieve_url_referrer_from_the_http_context() { typeof(HomeController)
    .GetMethod("GetHttpReferrer")
    .should_be_attributed_with<HttpReferrerAttribute>(); } }

    The first observation checks that the url referrer is being passed to the view (via the ViewData). Note that there are no dependencies on HttpContext for this controller, which makes it incredibly easy to test.

    The second observation checks that our ActionFilter is actually going to inject the correct url referrer value at runtime into our parameter – i.e. we have applied the parameter to the action! The should_be_attributed_with() extension method simply wraps another call to an MBUnit assert that the method signature has the custom attribute:

    public static void should_be_attributed_with<T>
    (this MethodInfo method) where T :
    Attribute { method.GetCustomAttributes(typeof(T), false)
    .Length.should_be_equal_to(1); }

    So now if we need to access the url referrer in another action all we need to do is apply the ActionFilter attribute and we know it will be provided at runtime. We can also write specifications to check that this attribute is present.

     

    Summary.

    Hopefully this has shown that ActionFilters are a great way to inject parameters into controller actions at runtime. This means they can be used to retrieve and provide run-time dependent values (e.g. from HttpContext) to the controllers which keeps the controllers clean, simple and easily tested. The result is reusable, crossing cutting functionality, with clear separation of concerns that makes for a maintainable, testable solution.

    A full working MVC project example for this code is available on CodePlex at:

    http://jamesbroome.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=32061

  • Asp.Net MVC – Separation of concerns amongst team members

     

    One of the clear advantages of using the MVC pattern is that it encourages separation of concerns – it doesn’t enforce it by any means, but following the pattern results in a nice clean, maintainable, flexible solution. The architectural advantages of this are documented everywhere, but I also believe that it aids separation of concerns in another way – in the roles of the project team members.

    I’m lucky enough to work in an environment where we have a team made up of .Net developers (C#), UI developers (HTML, CSS, Javascript), and database developers (SQL). Each of these roles performs a different function, has a different skill set, work on separate parts of the application and have separate tasks during a sprint.

    In the past, when working with WebForms, as a .Net developer I would spend a large amount of time in the UI layer, adding user controls to .aspx markup, and trying to explain to the UI developer how the “cssclass” attribute worked, why elements where rendered differently at runtime than they appeared in the code editor etc etc. It all felt a bit wrong. Because we are using Asp.Net MVC, on my current project we can both work side by side on a feature without treading on each others toes. We can deliver quicker and we have less breaking changes. I don’t put .Net code in the UI mark-up and the UI developer doesn’t put CSS styles in .Net code.

    On my current project, our UI developer didn’t join the team until after Sprint 4 – that’s 8 weeks of development without a proper UI in place. However, at the end of each of those 2 week sprints, we presented our application to the client as working software and planned out what we were going to do next, all the time, completely ignoring the UI. We were lucky in that our client understood and trusted us when we said that the UI would be designed and built without any impact to the underlying functionality we had already developed.

    And, after Sprint 4, when our UI developer joined the team, we went from presenting an application that looked like an out-of-the-box Asp.Net MVC application you get in Visual Studio, to a rich, professional, fully branded website in the space of one two-week sprint.  He was able to completely re-skin the entire UI using HTML and CSS (helped by the fact that we’re using the beautiful Spark View Engine) without me having to change a single line of C#. Now that’s what I call separation of concerns.

  • A response to “Deferring Costs to Future Generations”

     

    I read my colleague Simon Munro’s recent post about deferring costs to the future and how he thinks this should apply to the software development process. As a developer who is an advocate of all the things that Simon claims are simply improving future maintainability at a higher cost, I felt compelled to give a different opinion.

    On my current project, the timescales are short and the budget is tight. The pace is fast and the requirements are evolving and changing on a weekly, if not daily basis. This is why we run Agile projects – to be able to adapt quickly and change direction, focus, or scope as the project evolves. As with any software project, what a client wanted at the outset is practically guaranteed to differ from what they want when the time comes to “go live”. So, we work in short iterations, allowing for continuous feedback and input from the client – checkpoints along the way to make sure we’ve understood the requirements correctly, that the requirements are still valid and the client is happy with what we’re doing.

    The concepts that Simon refers to – Test Driven Development (TDD) and good software craftsmanship, practices and principles are, in my opinion, essential in the delivery of Agile software projects. Yes, TDD makes a solution more maintainable down the line because you quickly know if you’ve broken something, but I think that the argument that its sole benefit is maintainability is a pretty naive one.

    “Trendy software developers have recently been going on a lot about TDD, software craftsmanship, practices and principles that further the ability of software development teams to build good, reliable, fast, secure and maintainable software. A big part of the current themes is maintainability – with lots of statistics relating to the total cost of software over its lifetime indicating that the initial development costs are minimal (say30%) compared to the cost of maintenance in future.”

    I don’t consider myself a trendy software developer, but I do consider myself a good software developer. In my opinion, all of these engineering practises are about eliminating waste from the development process. If it’s costs that we’re worried about, then I would argue that adhering to and following this principles will save you money – and not just in phases 2 and 3 of the project, but during the initial development phase. I want to take each of the points Simon mentions and give reasons, aside from future maintainability, why they are necessary in delivering better software faster.

    “Tests are written, concerns are separated, control is inverted, things are decoupled, design is done by writing tests and refactoring is frequent – with one of the benefits being a system that can be easily maintained”

    Test Driven Development

    On my current project, we’re using Behaviour Driven Development (BDD) – a kind of mash-up between TDD and Domain Driven Design (DDD). The reason for this approach is exactly the same reason that Simon gives for not doing this kind of thing – short timescales, small budget. The real benefit is the middle D – “Driven”. The tests (or in our case the specifications) drive the development. 

    • Our specifications (tests) follow our requirements or user stories. If I work on a new task, writing out the specifications for this task first gives me a clear idea of when I’ve covered all the requirements. I don’t write specifications for requirements that aren’t there, therefore I don’t waste time over engineering the solution.
    • I then make the solution compile by adding in the components needed to satisfy the specifications. I don’t add anything that the specifications don’t need and therefore don’t waste time over engineering the solution. I only add code that adds business value.
    • I then make the specifications valid (make the tests pass) by implementing the code in the new components. I have only added what is needed to meet the requirements.
    • If I hadn’t written my tests first, how would I know when I am done? How would I know what components I needed. Ok, fair enough, I could have had a fair estimate at what it is I needed to do, but by committing the requirements to code in the form of specifications or tests first, I know exactly when I can move on and start the next feature.
    • Another side effect of committing the specifications to code is that we can easily generate a report of all the specifications in the system. We use JP Boohoo’s bdddoc tool to do this. This can give a non-technical user (the client, a project manager, a business analyst) a concrete view of what it is that the code actually does at any point in time.

    Inversion Of Control

    Because of the design principles of Dependency Injection and Inversion of Control I can write my tests quickly and concentrate on the “system under test” – i.e. the specific thing that I am developing. I can “mock-out” external dependencies – other components, databases, external services etc and they’re expected behaviours to allow me to simulate what happens in those situations. This means there’s no unexpected surprises further down the line when everything is integrated together. This isn’t about maintainability – it’s about reducing the number of bugs that will occur when components and functionality are integrated together during the day to day delivery of the project.

    Loose coupling

    During my last sprint review I demoed a checkout process that worked using a fake payment service. This was because the decision on the actual payment service to be used had not been finalised, but because my solution is loosely coupled this did not matter. I was able to demo working software to the client quicker because of this design principle. When the real payment service implementation is implemented, the amount of refactoring is minimal as the service will conform to the contract that we have defined and are coding against.

    Refactoring

    Things change. Requirements change. Technology changes. What I do this week may be redundant next week if the client changes their mind. I need to be able to refactor. If I can’t refactor easily or without fear then we have a problem. This isn’t for maintainability in the future, this is about changing things now without immediately introducing bugs that our System Tester has to raise and re-test once fixed. More time wasted.

    Everybody isn’t perfect all the time. People have off-days and people will write code that isn’t always as good as it could be. As I have a solid set of test coverage I can refactor code in the solution (not just my own) mercilessly without fear. I refactor code on a daily basis.

    Separation Of Concerns

    Our “concerns are separated”. We are using Asp.Net MVC and we are following Sharp Architecture, a solid architectural foundation for MVC applications. We are lucky enough to work on a project where we have .Net developers and UI Developers. These are different roles, with different skill sets. Because we are using Asp.Net MVC we can both work side by side on a feature without treading on each others toes. We can deliver quicker and we have less breaking changes. I don’t put .Net code in the UI mark-up and the IDev doesn’t put CSS styles in .Net code. I don’t really know why I have to even argue this one.

    Continuous Integration

    Our Continuous Integration process builds our solution and runs all the tests every time something is checked in. If for some reason it fails, we are notified immediately. Our System Tester can only take and deploy successful builds. No time is wasted on deploying and testing broken builds.

    Summary

    “This advice, I believe, applies to organizations (obviously), teams and individuals – would you want to be branded in the office as the developer that always estimates that things will take three times longer than your peers? How is that going to impact your career when jobs are on the line?”

    I don’t agree that by using good engineering practises my estimates are going to be three times longer. I would argue that I work quicker than a lot of my colleagues because of all the things mentioned above. Projects that aren’t running test-first with CI and good solution architecture are the ones that get delayed and over run in the end due to massive backlogs of bugs and time consuming change requests.

    I also don’t see the point in under-estimating something to try and give a better impression of how good a developer you are. That’s just ridiculous. When jobs are on the line, companies are looking for the best quality people, not the people who gives the lowest estimates. You can’t hide from the fact that something doesn’t work or isn’t finished no matter how quickly you said you’d do it.

    The point I think that Simon is trying to argue is that we shouldn’t over engineer solutions unnecessarily “just in case”, which I agree with. “You ain’t gonna need it” is another good development principle which is really enforced when working test-first (especially if using BDD). However, over-engineering a solution is very different from using good engineering practices to develop a solution. I am a consultant and have a responsibility to deliver the best possible solution for the client given the requirements, scope and budget. Without following the (widely accepted) solid engineering practices detailed above, I strongly believe that I am unable to do this.

  • Why I like N2 CMS

     

    My current project requires both e-commerce and content management features at the core of its solution. Whilst this would seem to be a fairly obvious and common requirement, the current offerings in the .Net world seem to be lacking when you try to consider both requirements. Sure, there are some great .Net CMS tools (Umbraco being my favourite) and there a number of e-commerce frameworks to pick from, but there seems to be a bit of a void when looking for an enterprise scale e-commerce framework that includes a fully featured CMS system.

    Howard posted recently about the state of play of open source CMS in the .Net world. The outcome of this investigation was that we chose N2 CMS as our content management framework and have been working with and building our site around this tool for the last few weeks. Here’s some initial thoughts around why I think N2 is the right choice for our solution.

     

    It doesn’t take over the solution.

    N2 is a CMS framework, not a fully blown CMS solution that you install and have to work around they way it does things. In fact, you can integrate N2 into an existing website, however it has been built, by using the N2 API – it’s really flexible in terms of how involved you want N2 to be in your application. You could make the decision to use N2 to manage your CMS requirements even if only 1% of your overall solution needed CMS functionality. It doesn’t have to be “an N2 site” in the way that it would do with Umbraco for example. In fact, you could use N2 without a website at all – the API would integrate into any kind of solution.

    That said, if your website is a pure CMS solution then N2 can be used as the core of the system. They also provide a fully featured example site to get you up and running.

    N2 does not impose a particular style of development.

    I think Umbraco is great, but I dislike editing code, templates, macros etc through the admin interface. N2 means we can code in the way we want to, developing as we would do normally using good solid development engineering practices and tools. Content definitions are built up in .Net code, which means we can follow OO principles and they can be unit tested and refactored easily like any other piece of code. The N2 source code is available so if you wish you can see the inner workings and even modify if you want to. Its built on a good technology stack - .Net, Castle Windsor, NHibernate and SQL Server, which fits exactly with the rest of our solution.

    It sits nicely with Asp.Net MVC (so far).

    Our public facing website is built using Asp.Net MVC. N2 include an example of how to use a custom N2 route with MVC which means that it will intercept incoming requests first and try to process them. Admittedly, this example is no where near as advanced as the templates site, but its working well for us so far. I think as our solution becomes more complex we may encounter some complexities with the route definitions, but Asp.Net MVC routing is very flexible and customisable so I think we will be able to solve anything that doesn’t hang well straight away with the N2 content route.

    The out-the-box admin interface also sits nicely side by side with an MVC application. We have two projects in our solution – one MVC application with our code in it and then a Web Forms application which contains the N2 Edit Site code (unmodified). We just link the two together via a virtual directory in IIS and everything fits seamlessly.

    It has a great API.

    For an open source project the documentation is quite good, with a number of examples. This is being built on by the N2 community in the form of a wiki, and also an active discussion forum. However, who needs documentation when you have an API like this:

    return N2.Find.Items.Where.Name.Eq(pageName).And.Type.Eq(typeof(HelpPage)).Select();

     

    So, for now, I’m very happy with N2. I get the feeling this may well be the subject of a number of posts in the coming weeks…

Powered by Community Server (Personal Edition), by Telligent Systems