<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arrange Act Assert &#187; Asp.Net MVC</title>
	<atom:link href="http://www.arrangeactassert.com/category/asp-net-mvc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.arrangeactassert.com</link>
	<description>Jag Reehal on Agile Development, ASP.NET MVC, Silverlight and all manner of good stuff</description>
	<lastBuildDate>Wed, 28 Jul 2010 06:22:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Creating the animals game using Asp.Net MVC, jQuery and jQueryUI</title>
		<link>http://www.arrangeactassert.com/creating-the-animals-game-using-asp-net-mvc-jquery-and-jqueryui/</link>
		<comments>http://www.arrangeactassert.com/creating-the-animals-game-using-asp-net-mvc-jquery-and-jqueryui/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 09:36:50 +0000</pubDate>
		<dc:creator>Jag Reehal</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[Unit tests]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery UI]]></category>

		<guid isPermaLink="false">http://www.arrangeactassert.com/?p=483</guid>
		<description><![CDATA[A few weeks ago we had some fun creating a demo for a game using the jQuery and jQuery UI libraries in the ‘Having fun with jQuery UI’ blog post. In this post we will go through how to create the game using ASP.NET MVC, jQuery and jQuery UI. The screenshot below shows the game [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago we had some fun creating a demo for a game using the jQuery and jQuery UI libraries in the <a href="http://www.arrangeactassert.com/having-fun-with-jquery-ui/">‘Having fun with jQuery UI</a>’ blog post. </p>
<p>In this post we will go through how to create the game using <a href="http://www.asp.net/mvc/">ASP.NET MVC</a>, <a href="http://jquery.com/">jQuery</a> and <a href="http://jqueryui.com/">jQuery UI</a>. </p>
<p>The screenshot below shows the game running.  </p>
<p><img src="http://www.arrangeactassert.com/wp-content/themes/resources/images/ScreenshotOfGameUsingASP.NET-MVC-jQueryAndjQueryUI.png" alt="Screenshot of Game using Asp.Net MVC, jQuery and jQueryUI" /></p>
<p>The code used for creating the game in ASP.NET MVC, jQuery and jQuery UI can be downloaded <a href="http://cid-8a29bf85dc9538dc.skydrive.live.com/self.aspx/.Public/GameUsingAspNetMVCandJQueryUI.zip">here</a>.  </p>
<h3 class="subheading">Getting Started</h3>
<p>Instead of three animals used in the demo, the game now contains fourteen.   I’ve created a repository which returns the animals.  To keep things simple there’s no database here, instead the animals are hard coded.  </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System.Linq;
using GameUsingAspNetMVCandJQueryUI.Core.Models;

namespace GameUsingAspNetMVCandJQueryUI.Core.Repository
{
    public class AnimalsRepository : IAnimalsRepository
    {
        public IQueryable&lt;Animal&gt; GetAll()
        {
            return new Animal[]
                       {
                           new Animal(){Name = &quot;Cow&quot;},
                           new Animal(){Name = &quot;Cat&quot;},
                           new Animal(){Name = &quot;Chicken&quot;},
                           new Animal(){Name = &quot;Dog&quot;},
                           new Animal(){Name = &quot;Elephant&quot;},
                           new Animal(){Name = &quot;Giraffe&quot;},
                           new Animal(){Name = &quot;Hippo&quot;},
                           new Animal(){Name = &quot;Lion&quot;},
                           new Animal(){Name = &quot;Monkey&quot;},
                           new Animal(){Name = &quot;Mouse&quot;},
                           new Animal(){Name = &quot;Owl&quot;},
                           new Animal(){Name = &quot;Penguin&quot;},
                           new Animal(){Name = &quot;Pig&quot;},
                           new Animal(){Name = &quot;Sheep&quot;},
                       }
                .AsQueryable();
        }
    }
}
</pre>
<h3 class="subheading">Command Query Separation</h3>
<p>One of the features I have added is to ensure a correct answer for the current game could not be the correct answer in the next.  As the repository class was responsible for getting animals, having it contain any logic would violate good design principles.  </p>
<p>So the logic goes into the service layer which returns a data transfer object for animals and the correct answer.   </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System.Linq;
using GameUsingAspNetMVCandJQueryUI.Core.ExtensionMethods;
using GameUsingAspNetMVCandJQueryUI.Core.Models;
using GameUsingAspNetMVCandJQueryUI.Core.Repository;

namespace GameUsingAspNetMVCandJQueryUI.Core.Service
{
    public class AnimalsService : IAnimalsService
    {
        private readonly IAnimalsRepository _animalsRepository;

        public AnimalsService(IAnimalsRepository animalsRepository)
        {
            _animalsRepository = animalsRepository;
        }

        public AnimalsDto GetAnimalsForGameWithCorrectAnswer(int numberOfAnimals, string previousAnimal)
        {
            AnimalsDto animalsDto = new AnimalsDto();
            animalsDto.Animals = _animalsRepository
                .GetAll()
                .Where(a =&gt; a.Name != previousAnimal)
                .Shuffle()
                .Take(numberOfAnimals);

            animalsDto.CorrectAnswer = animalsDto.Animals.Shuffle().First().Name;

            return animalsDto;
        }
    }
}
</pre>
<p>This also makes testing easier because the tests can focus on making sure the service is doing what it should like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using System.Linq;
using GameUsingAspNetMVCandJQueryUI.Core.Models;
using GameUsingAspNetMVCandJQueryUI.Core.Repository;
using GameUsingAspNetMVCandJQueryUI.Core.Service;
using NBehave.Spec.NUnit;
using NUnit.Framework;
using Rhino.Mocks;

namespace GameUsingAspNetMVCandJQueryUI.Tests
{
    [TestFixture]
    public class AnimalsServiceTests
    {
        private IAnimalsService _animalsService;
        private IAnimalsRepository _animalsRepository;

        private readonly IQueryable&lt;Animal&gt; _animalsStub = new Animal[]
                           {
                               new Animal(){Name = &quot;Cow&quot;},
                               new Animal(){Name = &quot;Pig&quot;},
                               new Animal(){Name = &quot;Sheep&quot;},
                           }.AsQueryable();

        [SetUp]
        public void SetUp()
        {
            _animalsRepository = MockRepository.GenerateStub&lt;IAnimalsRepository&gt;();
            _animalsService = new AnimalsService(_animalsRepository);
        }

        [Test]
        public void Should_Exclude_Previous_Animal_When_Previous_Animal_Is_Passed_In()
        {
            // Arrange
            _animalsRepository.Stub(a =&gt; a.GetAll()).Return(_animalsStub);
            var previousAnimal = _animalsStub.First();

            // Act
            var result = _animalsService.GetAnimalsForGameWithCorrectAnswer(3, previousAnimal.Name);

            // Assert
            result.Animals.Count(a =&gt; a.Name == previousAnimal.Name).ShouldEqual(0);
        }

        [Test]
        public void Should_Return_All_Animals_When_No_Previous_Animal_Is_Passed_In()
        {
            // Arrange
            _animalsRepository.Stub(a =&gt; a.GetAll()).Return(_animalsStub);
            string previousAnimal = String.Empty;

            // Act
            var result = _animalsService.GetAnimalsForGameWithCorrectAnswer(3, previousAnimal);

            // Assert
            result..Animals.Count().ShouldEqual(3);
        }

        [Test]
        public void Should_Return_All_Animals_When_No_Previous_Animal_Is_Null()
        {
            // Arrange
            _animalsRepository.Stub(a =&gt; a.GetAll()).Return(_animalsStub);
            string previousAnimal = null;

            // Act
            var result = _animalsService.GetAnimalsForGameWithCorrectAnswer(3, previousAnimal);

            // Assert
            result.Animals.Count().ShouldEqual(3);
        }

        [Test]
        public void Correct_Answer_Should_Not_Be_Empty()
        {
            // Arrange
            _animalsRepository.Stub(a =&gt; a.GetAll()).Return(_animalsStub);            

            // Act
            var result = _animalsService.GetAnimalsForGameWithCorrectAnswer(3, null);

            // Assert
            result.CorrectAnswer.ShouldNotBeEmpty();
        }
    }
}
</pre>
<h3 class="subheading">The LINQ Shuffle</h3>
<p>Even though we have removed the previous answer, if the animals were returned as they are the answer would just be the next one in the list.  So to keep the game exciting, a shuffle extension method is used to shuffle the answers.  </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using System.Collections.Generic;
using System.Linq;

namespace GameUsingAspNetMVCandJQueryUI
{
    public static class GameExtensions
    {
        public static IEnumerable&lt;T&gt; Shuffle&lt;T&gt;(this IEnumerable&lt;T&gt; items)
        {
            var rnd = new Random();
            IEnumerable&lt;int&gt; numbers = Enumerable.Range(0, items.Count()).OrderBy(r =&gt; rnd.Next());
            var randomItems = new List&lt;T&gt;();
            foreach (int number in numbers)
            {
                randomItems.Add(items.Skip(number).First());
            }
            return randomItems;
        }
    }
}
</pre>
<p>This can be unit tested as shown below</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System.Collections.Generic;
using System.Linq;
using GameUsingAspNetMVCandJQueryUI.Core.Models;
using NUnit.Framework;

namespace GameUsingAspNetMVCandJQueryUI.Tests
{
    [TestFixture]
    public class GameExtensionsTests
    {
        [Test]
        public void Can_Shuffle_Animals()
        {
            List&lt;Animal&gt; animals = new List&lt;Animal&gt;()
                           {
                               new Animal(){Name = &quot;Cow&quot;},
                               new Animal(){Name = &quot;Pig&quot;},
                               new Animal(){Name = &quot;Sheep&quot;},
                           };
            IList&lt;Animal&gt; result = animals.Shuffle().ToList();
            Assert.IsFalse(
                animals[0].Equals(result[0]) &amp;&amp;
                animals[1].Equals(result[1]) &amp;&amp;
                animals[2].Equals(result[2]),
                &quot;Animals should have been shuffled&quot;);
        }
    }
}
</pre>
<h3 class="subheading">What happens when a player opens the game in their browser?</h3>
<p>When the page loads an Ajax call is made using jQuery to an Asp.Net MVC action method which returns a JsonResult.  </p>
<pre class="brush: jscript; gutter: false; toolbar: true;">
   $.getJSON(&quot;/Game/GetAnimals&quot;,
            { numberOfAnimals: numberOfItemsToGet, previousAnimal: correctAnswer.text() },
            function(data) {
                addItems(data);
                $(&quot;#droppable&quot;).droppable(droppableOptions);
                assignDraggables();
                hideItemsForLevel();
                setUpSlider();
                setTimeout(function() {
                    instructions.text(instructionsText);
                    items.show();
                }, 1000);
            });
</pre>
<p>Two parameters are passed to the action method, one for the previous answer and the other for the number of animals required.  The reason for this is because we don’t want to transfer more data over the wire than required, why return fourteen animals when only six are required?  </p>
<p>The ‘GetAnimals’ Asp.Net MVC action method shown below serializes the view model returned by the service layer into JSON. </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System.Web.Mvc;
using GameUsingAspNetMVCandJQueryUI.Core.Service;

namespace GameUsingAspNetMVCandJQueryUI.Controllers
{
    [HandleError]
    public class GameController : Controller
    {
        private readonly IAnimalsService _animalsService;

        public GameController(IAnimalsService animalsService)
        {
            _animalsService = animalsService;
        }

        public ActionResult Index()
        {
            return View(&quot;Index&quot;);
        }

        [OutputCache(NoStore = true, Duration = 0, VaryByParam = &quot;*&quot;)]
        public JsonResult GetAnimals(int numberOfAnimals, string previousAnimal)
        {
            return Json(_animalsService.GetAnimalsForGameWithCorrectAnswer(numberOfAnimals,previousAnimal));
        }
    }
}
</pre>
<blockquote><p>Notice how I have to be explicit about how I do NOT want the JsonResult to be cached.  If you don&#8217;t add this Internet Explorer will cache the result and you will get the same animals. </p></blockquote>
<h3 class="subheading">Using the jQuery and jQuery UI in the ASP.NET MVC View</h3>
<p>The JavaScript used the demo was good enough to perform the dragging and dropping of pictures so the good news is we can use it again here.  </p>
<p>An additional feature I have added is to allow the player to change the difficulty of the game by choosing how many animals are shown on the screen. </p>
<p>To do this I used the jQuery UI slider and jQuery fade functionality.  The reason I used fade rather show/hide in jQuery was because I didn’t want the animals to move position when a user changed the difficulty as this would have resulted in a poor user experience by confusing the player.</p>
<p>Currently the message which tells the player if they have selected an incorrect answer is shown when the user stops dragging the animal.  This is a problem because if the user drags a correct animal but doesn’t drop it on the droppable a message isn’t shown.  If I find a fix for this I’ll update the code and this post.</p>
<h3 class="subheading">Jag Reehal’s Final Thought on ‘Creating the animals game using Asp.Net MVC, jQuery and jQueryUI’ </h3>
<p>I’ve been using jQuery for a while now and I still love it.  </p>
<p>The jQuery UI library is very good and the <a href="http://jqueryui.com/about">jQuery UI team</a> have done a fantastic job creating demos and documentation.  </p>
<p>I really like how you can create your own custom javascript file which only contains the features you require from the library.  </p>
<p>No doubt some people will question why the service is returning a data transfer object.  I could have returned a collection of animals to the ASP.NET MVC controller and have it create an object to pass to the view.  The reason I didn’t do this is because I know the data transfer object will be used by another user interface layer (Silverlight) and because this would have bloated the controller and that’s not good.  A <a href="http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%E2%80%93-skinny-controllers/">best practice for ASP.NET MVC is to have skinny controllers</a>.     </p>
<p>The images for the animals used in the game are from <a href="http://www.openclipart.org">http://www.openclipart.org</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.arrangeactassert.com/creating-the-animals-game-using-asp-net-mvc-jquery-and-jqueryui/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ASP.NET MVC View Best Practices – Save time creating views with MvcContrib.FluentHtml</title>
		<link>http://www.arrangeactassert.com/asp-net-mvc-view-best-practices-save-time-creating-views-with-mvccontrib-fluenthtml/</link>
		<comments>http://www.arrangeactassert.com/asp-net-mvc-view-best-practices-save-time-creating-views-with-mvccontrib-fluenthtml/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 07:34:39 +0000</pubDate>
		<dc:creator>Jag Reehal</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>

		<guid isPermaLink="false">http://www.arrangeactassert.com/?p=358</guid>
		<description><![CDATA[This isn’t strictly a best practice post, but it is now I am currently creating html in my ASP.NET MVC views. It must be a good approach because Microsoft are implementing Templated Helpers to do what I&#8217;m showing you today in ASP.NET MVC 2. See Ben Scheirmans&#8217; post A First Look at ASP.NET MVC 2 [...]]]></description>
			<content:encoded><![CDATA[<p>This isn’t strictly a best practice post, but it is now I am currently creating html in my ASP.NET MVC views.  </p>
<p>It must be a good approach because Microsoft are implementing Templated Helpers to do what I&#8217;m showing you today in ASP.NET MVC 2.  See <a href="http://dotnetslackers.com/articles/aspnet/A-First-Look-at-ASP-NET-MVC-2.aspx">Ben Scheirmans&#8217; post A First Look at ASP.NET MVC 2</a> for more information.  </p>
<p>In this post I want to show you two view implementations based on adapted versions of the Account Controller and LogOn view which are created whenever you do File > New > Project > ASP.NET MVC Web Application.</p>
<p>The slimmed down AccountController looks like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using System.Web.Mvc;

namespace AspNetMvcViewBestPractices.Controllers
{
    public class AccountController : Controller
    {
        public ActionResult LogOn()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult LogOn(string UserName, string Password, bool RememberMe)
        {
            if (!ValidateLogOn(UserName, Password))
            {
                return View();
            }

            return RedirectToAction(&quot;Index&quot;, &quot;Product&quot;);
        }

        private bool ValidateLogOn(string userName, string password)
        {
            if (String.IsNullOrEmpty(userName))
            {
                ModelState.AddModelError(&quot;UserName&quot;, &quot;You must specify a username.&quot;);
            }
            if (String.IsNullOrEmpty(password))
            {
                ModelState.AddModelError(&quot;Password&quot;, &quot;You must specify a password.&quot;);
            }
            if (!(userName == &quot;admin&quot; &amp;&amp; password == &quot;password&quot;))
            {
                ModelState.AddModelError(&quot;_FORM&quot;, &quot;The username or password provided is incorrect.&quot;);
            }

            return ModelState.IsValid;
        }
    }
}
</pre>
<p>The LogOn view is shown below</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;%@ Page Title=&quot;&quot; Language=&quot;C#&quot; MasterPageFile=&quot;~/Views/Shared/Site.Master&quot; Inherits=&quot;System.Web.Mvc.ViewPage&quot; %&gt;

&lt;asp:Content ID=&quot;loginContent&quot; ContentPlaceHolderID=&quot;MainContent&quot; runat=&quot;server&quot;&gt;
    &lt;h2&gt;Log On&lt;/h2&gt;

    &lt;%= Html.ValidationSummary(&quot;Login was unsuccessful. Please correct the errors and try again.&quot;) %&gt;

    &lt;% using (Html.BeginForm()) { %&gt;
        &lt;div&gt;
            &lt;fieldset&gt;
                &lt;legend&gt;Account Information&lt;/legend&gt;
                &lt;p&gt;
                    &lt;label for=&quot;UserName&quot;&gt;UserName&lt;/label&gt;
                    &lt;%= Html.TextBox(&quot;UserName&quot;) %&gt;
                    &lt;%= Html.ValidationMessage(&quot;UserName&quot;) %&gt;
                &lt;/p&gt;
                &lt;p&gt;
                    &lt;label for=&quot;Password&quot;&gt;Password&lt;/label&gt;
                    &lt;%= Html.Password(&quot;Password&quot;) %&gt;
                    &lt;%= Html.ValidationMessage(&quot;Password&quot;) %&gt;
                &lt;/p&gt;
                &lt;p&gt;
                    &lt;%= Html.CheckBox(&quot;RememberMe&quot;) %&gt; &lt;label class=&quot;inline&quot; for=&quot;RememberMe&quot;&gt;Remember me?&lt;/label&gt;
                &lt;/p&gt;
                &lt;p&gt;
                    &lt;input type=&quot;submit&quot; value=&quot;Log On&quot; /&gt;
                &lt;/p&gt;
            &lt;/fieldset&gt;
        &lt;/div&gt;
    &lt;% } %&gt;
&lt;/asp:Content&gt;
</pre>
<p>There are two problems I have this view.  The first is that everything is tightly coupled using what are known as magic strings.  For example if you change the line</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;%= Html.TextBox(&quot;UserName&quot;) %&gt;
</pre>
<p>to</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;%= Html.TextBox(&quot;Username&quot;) %&gt;
</pre>
<p>the UserName argument in the LogOn form post action no longer gets populated when the form is submitted.  This is because the name for the id in the form and name in the method signature need to be the same.</p>
<p>The other is the amount of html you have to manually write.  Sometimes Visual Studio can tell you if have made a typo in your html mark up, but not always.  For example it can’t detect an error like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;input type=&quot;sumbit&quot; /&gt;
</pre>
<p>As I mentioned in my previous post unless you go through the laborious process of creating front end tests, the first time you will notice is when you view the website in a browser or one of your customers tell you.</p>
<h3 class="subheading">How I would create the LogOn view</h3>
<p>1. Create a LogOnForm data transfer object (DTO)</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
namespace AspNetMvcViewBestPractices.Models
{
    public class LogOnForm
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public bool RememberMe { get; set; }
    }
}
</pre>
<p>2. Change the signature of the Account controllers’ LogOn post action to take in the LogOnForm DTO.  This model will be populated by the ASP.NET MVC model binders using the form values.</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(LogOnForm logOnForm)
{
    if (!ValidateLogOn(logOnForm.UserName, logOnForm.Password))
    {
        return View(logOnForm);
    }

    return RedirectToAction(&quot;Index&quot;, &quot;Product&quot;);
}
</pre>
<p>3. Add a reference to the <a href="http://mvccontrib.codeplex.com/Wiki/View.aspx?title=FluentHtml">MvcContrib.FluentHtml</a> assembly.</p>
<p>4. Change the view so it inherits from &#8216;MvcContrib.FluentHtml.ModelViewPage<LogOnForm>&#8216;.</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;%@ Page Title=&quot;&quot; Language=&quot;C#&quot; MasterPageFile=&quot;~/Views/Shared/Site.Master&quot; Inherits=&quot;MvcContrib.FluentHtml.ModelViewPage&lt;LogOnForm&gt;&quot; %&gt;
</pre>
<p>5. Use the MvcContrib.FluentHtml assembly to create the html in the view</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
            &lt;fieldset&gt;
                &lt;legend&gt;Account Information&lt;/legend&gt;
                &lt;p&gt;
                   &lt;%=this.TextBox(m =&gt; m.UserName).Label(&quot;UserName&quot;)%&gt;
                   &lt;%=this.ValidationMessage(m =&gt; m.UserName)%&gt;
                &lt;/p&gt;
                &lt;p&gt;
                   &lt;%=this.TextBox(m =&gt; m.Password).Label(&quot;Password&quot;)%&gt;
                   &lt;%=this.ValidationMessage(m =&gt; m.Password )%&gt;
                &lt;/p&gt;
                &lt;p&gt;
                    &lt;%=this.CheckBox(c =&gt; c.RememberMe).LabelAfter(&quot; Remember me?&quot;,&quot;inline&quot;)%&gt;
                &lt;/p&gt;
                &lt;p&gt;
                    &lt;%=this.SubmitButton(&quot;Log On&quot;) %&gt;
                &lt;/p&gt;
            &lt;/fieldset&gt;
</pre>
<p>Now there is less chance of any html typos in the view and we no longer have magic strings for the ids of the input fields.  The MvcContrib.FluentHtml assembly can generate the ids from the property names in the view model for you automatically. </p>
<p>This means you no longer have to search for strings in views if you change the name of a property.</p>
<p>If you’re at all worried about the html generated by the MvcContrib.FluentHtml assembly don’t be, it’s as good if you had written it yourself.</p>
<p>For more information about the MvcContrib.FluentHtml assembly check out blog posts below:</p>
<ul>
<li><a href="http://lunaverse.wordpress.com/2008/11/24/mvcfluenthtml-fluent-html-interface-for-ms-mvc">MvcFluentHtml – Fluent HTML Interface For MS MVC</a></li>
<li><a href="http://lunaverse.wordpress.com/2009/01/13/editing-a-variable-length-list-of-items-with-mvccontribfluenthtml-take-2">Editing a Variable Length List Of Items With MvcContrib.FluentHtml – Take 2</a></li>
<li><a href="http://lunaverse.wordpress.com/2009/02/05/eliminate-magic-strings-in-javascript-with-mvccontribfluenthtml">Eliminate Magic Strings In Javascript With MvcContrib.FluentHtml</a></li>
</ul>
<h3 class="subheading">What about ASP.NET MVC 2?</h3>
<p>In ASP.NET MVC 2 the DisplayFor html helper can be used to create the html for the model like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;%= Html.DisplayFor(m =&gt; m.Password) %&gt;
</pre>
<p>What it can&#8217;t do (at the time of writing) is any chaining for things like labels e.g. </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;%=this.TextBox(m =&gt; m.Password).Label(&quot;Password&quot;)%&gt;
</pre>
<h3 class="subheading">Jag Reehal’s Final Thought on ‘ASP.NET MVC View Best Practices – Save time creating views with MvcContrib.FluentHtml’ </h3>
<p>in this post I wanted to demonstrate the why at this moment in time I use the MvcContrib.FluentHtml assembly for creating html in my views. </p>
<p>It will definitely save you time and you will be more productive because you’re no longer going to write as much html plumbing code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.arrangeactassert.com/asp-net-mvc-view-best-practices-save-time-creating-views-with-mvccontrib-fluenthtml/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ASP.NET MVC View Best Practices – Keep logic out of your views</title>
		<link>http://www.arrangeactassert.com/asp-net-mvc-view-best-practices-keep-logic-out-of-your-views/</link>
		<comments>http://www.arrangeactassert.com/asp-net-mvc-view-best-practices-keep-logic-out-of-your-views/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 23:35:02 +0000</pubDate>
		<dc:creator>Jag Reehal</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[Unit tests]]></category>

		<guid isPermaLink="false">http://www.arrangeactassert.com/?p=319</guid>
		<description><![CDATA[When it comes to views in ASP.NET MVC, you won’t be short of options how you decide how to create them. One of the easiest mistakes is to implement logic in their views. It’s no surprise developers such as Rob Conery have advised against having conditional code in ASP.NET MVC views. Before you know it [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to views in ASP.NET MVC, you won’t be short of options how you decide how to create them.  </p>
<p>One of the easiest mistakes is to implement logic in their views. </p>
<p>It’s no surprise developers such as Rob Conery have advised against having conditional code in ASP.NET MVC views.  Before you know it a view that was simple and easy to understand becomes a complex monster intertwined with html and logic. </p>
<p>The code used in this post can be downloaded <a href="http://cid-8a29bf85dc9538dc.skydrive.live.com/self.aspx/.Public/AspNetMvcViewBestPractices.zip">here</a>.  </p>
<p>The fact is ASP.NET MVC views which contain logic will ultimately end up being a nightmare to maintain and test. </p>
<p>Here is an example of what I mean.  When displaying product information, our client wants to show to the number of units in stock.  The background colour should reflect the stock level as shown below (along with the css class name) </p>
<table class="blogTable">
<tr>
<th>Number In Stock</th>
<th>Colour should be</th>
<th>Css class name</th>
</tr>
<tr>
<td>0</td>
<td>Red</td>
<td>stockLevelNone</td>
</tr>
<tr>
<td>1-20</td>
<td>Yellow</td>
<td>stockLevelLow</td>
</tr>
<tr>
<td>Over 20</td>
<td>Green</td>
<td>stockLevelHigh</td>
</tr>
</table>
<p><br/><br />
This could be implemented by creating the view like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;div class=&quot;stockLevel
   &lt;%=Model.UnitsInStock == 0 ? &quot; stockLevelNone&quot; : String.Empty%&gt;
   &lt;%=Model.UnitsInStock &gt; 0 &amp;&amp; Model.UnitsInStock &lt;= 20 ? &quot; stockLevelLow&quot; : String.Empty%&gt;
   &lt;%=Model.UnitsInStock &gt; 20 ? &quot; stockLevelHigh&quot; : String.Empty%&gt;
   &quot;&gt;
    &lt;span&gt;Number Of Units In Stock: &lt;%=Model.UnitsInStock %&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>
<p>Because there is logic in the ASP.NET MVC view, you have to go through the laborious process of creating front end tests or creating a product, setting the number in stock and then checking the correct class is used by viewing the page source for each condition.  And if that wasn’t difficult enough, imagine doing that every time you do a release.</p>
<p>So what if I said there are alternative methods which could:</p>
<ul>
<li>reduce the chance of typos in your html</li>
<li>clean up your view</li>
<li>be testable</li>
<li>be reused so you can follow the “<a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don&#8217;t Repeat Yourself (DRY)</a>&#8221; principle which will save you so much time!</li>
</ul>
<h3 class="subheading">Option1 &#8211; Move the logic for choosing the css class into a helper method</h3>
<p>The conditional logic in the ASP.NET MVC view can be replaced by a method which takes in the number of units in stock and returns the appropriate css class as shown below.</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;

namespace AspNetMvcViewBestPractices.Helpers
{
    public static class ProductCssHelper
    {
        public const string STOCK_LEVEL_NONE_CSS_CLASS = &quot;stockLevelNone&quot;;
        public const string STOCK_LEVEL_LOW_CSS_CLASS = &quot;stockLevelLow&quot;;
        public const string STOCK_LEVEL_HIGH_CSS_CLASS = &quot;stockLevelHigh&quot;;

        public static string GetCssClassForUnitsInStock(int unitsInStock)
        {
            if (unitsInStock == 0)
            {
                return STOCK_LEVEL_NONE_CSS_CLASS;
            }
            if (unitsInStock &gt; 0 &amp;&amp; unitsInStock &lt;= 20)
            {
                return STOCK_LEVEL_LOW_CSS_CLASS;
            }
            if (unitsInStock &gt; 20)
            {
                return STOCK_LEVEL_HIGH_CSS_CLASS;
            }
            return String.Empty;
        }
    }
}
</pre>
<p>In the view the number of units in stock is passed to the css helper method </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;div class=&quot;stockLevel &lt;%=ProductCssHelper.GetCssClassForUnitsInStock(Model.UnitsInStock)%&gt;&quot;&gt;
    &lt;span&gt;Number Of Units In Stock: &lt;%=Model.UnitsInStock %&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>
<p>And the css helper method can now be unit tested as shown below</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using AspNetMvcViewBestPractices.Helpers;
using NUnit.Framework;

namespace AspNetMvcViewBestPractices.Tests
{
    [TestFixture]
    public class ProductCssHelperTests
    {
        [Test]
        public void Will_Return_StockLevelNone_Css_Class_If_There_Are_No_Units_In_Stock()
        {
            // Arrange
            int unitsInStock = 0;

            // Act
            string cssClass = ProductCssHelper.GetCssClassForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(ProductCssHelper.STOCK_LEVEL_NONE_CSS_CLASS,cssClass);
        }

        [Test]
        public void Will_Return_StockLevelLow_Css_Class_If_Units_In_Stock_Is_Between_One_And_Twenty(
            [Range(1, 20)] int unitsInStock)
        {
            // Arrange        

            // Act
            string cssClass = ProductCssHelper.GetCssClassForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(ProductCssHelper.STOCK_LEVEL_LOW_CSS_CLASS, cssClass);
        }

        [Test]
        public void Will_Return_StockLevelHigh_Css_Class_If_Units_In_Stock_Is_Over_Twenty()
        {
            // Arrange
            int unitsInStock = 21;

            // Act
            string cssClass = ProductCssHelper.GetCssClassForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(ProductCssHelper.STOCK_LEVEL_HIGH_CSS_CLASS, cssClass);
        }

        [Test]
        public void Will_Return_EmptyString_If_Units_In_Stock_Is_Less_Then_Zero()
        {
            // Arrange
            int unitsInStock = -1;

            // Act
            string cssClass = ProductCssHelper.GetCssClassForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(String.Empty, cssClass);
        }
    }
}
</pre>
<h3 class="subheading">Option 2 &#8211; Create a method to build the html for displaying the number of units in stock</h3>
<p>I first saw this approach in <a href=" http://code.google.com/p/sutekishop/">Mike Hadlows’ Suteki Shop</a>.  Here an html helper method takes in the number of units in stock and returns an html string</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;

namespace AspNetMvcViewBestPractices.Helpers
{
    public static class ProductHtmlHelper
    {
        public const string STOCK_LEVEL_NONE_CSS_CLASS = &quot;stockLevelNone&quot;;
        public const string STOCK_LEVEL_LOW_CSS_CLASS = &quot;stockLevelLow&quot;;
        public const string STOCK_LEVEL_HIGH_CSS_CLASS = &quot;stockLevelHigh&quot;;
        public const string UNITS_IN_STOCK_HTML = @&quot;&lt;div class=&quot;&quot;stockLevel {0}&quot;&quot;&gt;&lt;span&gt;Number Of Units In Stock: {1}&lt;/span&gt;&lt;/div&gt;&quot;;

        public static string GetHtmlForUnitsInStock(int unitsInStock)
        {
            if (unitsInStock == 0)
            {
                return String.Format(UNITS_IN_STOCK_HTML,STOCK_LEVEL_NONE_CSS_CLASS,unitsInStock);
            }
            if (unitsInStock &gt; 0 &amp;&amp; unitsInStock &lt;= 20)
            {
                return String.Format(UNITS_IN_STOCK_HTML, STOCK_LEVEL_LOW_CSS_CLASS, unitsInStock);
            }
            if (unitsInStock &gt; 20)
            {
                return String.Format(UNITS_IN_STOCK_HTML, STOCK_LEVEL_HIGH_CSS_CLASS, unitsInStock);
            }
            return String.Format(UNITS_IN_STOCK_HTML, String.Empty, unitsInStock);
        }
    }
}
</pre>
<p>In the view a call is made to the html helper method passing the number of units in stock</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;%=ProductHtmlHelper.GetHtmlForUnitsInStock(Model.UnitsInStock)%&gt;
</pre>
<p>The html helper can be unit tested like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using AspNetMvcViewBestPractices.Helpers;
using NUnit.Framework;

namespace AspNetMvcViewBestPractices.Tests
{
    [TestFixture]
    public class ProductHtmlHelperTests
    {
        [Test]
        public void Will_Return_StockLevelNone_Html_If_There_Are_No_Units_In_Stock()
        {
            // Arrange
            int unitsInStock = 0;
            string expectedResult = @&quot;&lt;div class=&quot;&quot;stockLevel stockLevelNone&quot;&quot;&gt;&lt;span&gt;Number Of Units In Stock: 0&lt;/span&gt;&lt;/div&gt;&quot;;

            // Act
            string html = ProductHtmlHelper.GetHtmlForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(expectedResult,html);
        }

        [Test]
        public void Will_Return_StockLevelLow_Html_If_Units_In_Stock_Is_Between_Zero_And_Twenty(
            [Range(1, 20)] int unitsInStock)
        {
            // Arrange
            string expectedResult = String.Format(@&quot;&lt;div class=&quot;&quot;stockLevel stockLevelLow&quot;&quot;&gt;&lt;span&gt;Number Of Units In Stock: {0}&lt;/span&gt;&lt;/div&gt;&quot;, unitsInStock);

            // Act
            string html = ProductHtmlHelper.GetHtmlForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(expectedResult, html);
        }

        [Test]
        public void Will_Return_StockLevelHigh_Html_If_Units_In_Stock_Is_Over_Twenty()
        {
            // Arrange
            int unitsInStock = 21;
            string expectedResult = @&quot;&lt;div class=&quot;&quot;stockLevel stockLevelHigh&quot;&quot;&gt;&lt;span&gt;Number Of Units In Stock: 21&lt;/span&gt;&lt;/div&gt;&quot;;

            // Act
            string html = ProductHtmlHelper.GetHtmlForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(expectedResult, html);
        }

        [Test]
        public void Will_Return_Html_With_NoStockLevelIndicator_If_Units_In_Stock_Is_Less_Then_Zero()
        {
            // Arrange
            int unitsInStock = -1;
            string expectedResult = @&quot;&lt;div class=&quot;&quot;stockLevel &quot;&quot;&gt;&lt;span&gt;Number Of Units In Stock: -1&lt;/span&gt;&lt;/div&gt;&quot;;

            // Act
            string html = ProductHtmlHelper.GetHtmlForUnitsInStock(unitsInStock);

            // Assert
            Assert.AreEqual(expectedResult, html);
        }
    }
}
</pre>
<h3 class="subheading">Option 3 &#8211; Use a Product data transfer object with a css class name property</h3>
<p>Instead of passing the product model into the view, we could map it into a data transfer object that has a property for the css class name.  For this to work the controller needs to perform the mapping before returning a model to the view.  I will be covering the why you should avoid using domain models directly into views in a future blog post.</p>
<p>The view model/data transfer object is shown below</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
namespace AspNetMvcViewBestPractices.Models
{
    public class ProductDto
    {
        public Product Product { get; set; }
        public string UnitsInStockCssClassName { get; set; }
    }
}
</pre>
<p>The mapping class looks like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using AspNetMvcViewBestPractices.Helpers;
using AspNetMvcViewBestPractices.Models;

namespace AspNetMvcViewBestPractices.Mappers
{
    public static class ProductDtoMapper
    {
        public static ProductDto Map(Product product)
        {
            ProductDto productDto = new ProductDto();
            productDto.Product = product;
            productDto.UnitsInStockCssClassName =  ProductCssHelper.GetCssClassForUnitsInStock(product.UnitsInStock);
            return productDto;
        }
    }
}
</pre>
<p>And can be unit tested like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using AspNetMvcViewBestPractices.Mappers;
using AspNetMvcViewBestPractices.Models;
using NUnit.Framework;

namespace AspNetMvcViewBestPractices.Tests
{
    [TestFixture]
    public class ProductDtoMapperTests
    {
        [Test]
        public void Can_Map_Product_to_ProductDto()
        {
            // Arrange
            Product product = new Product();
            product.UnitsInStock = 10;

            // Act
            ProductDto productDto = ProductDtoMapper.Map(product);

            // Assert
            Assert.AreEqual(product, productDto.Product);
        }
    }
}
</pre>
<p>The controller uses the Product mapper as shown below</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
public ActionResult DisplayProductUsingMapper()
{
    Product product = new Product();
    Random random = new Random();
    product.UnitsInStock = random.Next(0, 30);

    ProductDto productDto = ProductDtoMapper.Map(product);
    return View(productDto);
}
</pre>
<p>Now the view does not need to make any method calls and only uses properties in the view model</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;div class=&quot;stockLevel &lt;%=Model.UnitsInStockCssClassName%&gt;&quot;&gt;
    &lt;span&gt;Number Of Units In Stock: &lt;%=Model.Product.UnitsInStock %&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>
<h3 class="subheading">Option 4 &#8211; When you need to show all css options in the view</h3>
<p>I created this option after a comment I received.  If you&#8217;re working with designers and/or want to show the css classes in the view this option will be to go for.  Similar to first option we can use a css helper but this time we pass in the the number of units in stock and the css classes as shown below</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;

namespace AspNetMvcViewBestPractices.Helpers
{
    public static class ProductCssHelper
    {
        public static string SelectCssClassForUnitsInStock(int unitsInStock, string stockLevelNone, string stockLevelLow, string stockLevelHigh)
        {
            if (unitsInStock == 0)
            {
                return stockLevelNone;
            }
            if (unitsInStock &gt; 0 &amp;&amp; unitsInStock &lt;= 20)
            {
                return stockLevelLow;
            }
            if (unitsInStock &gt; 20)
            {
                return stockLevelHigh;
            }
            return String.Empty;
        }
    }
}
</pre>
<p>In the view the number of units in stock and the css classes are passed to the css helper method </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
&lt;div class=&quot;stockLevel &lt;%=ProductCssHelper.SelectCssClassForUnitsInStock(Model.UnitsInStock,&quot;stockLevelNone&quot;,&quot;stockLevelLow&quot;,&quot;stockLevelHigh&quot;)%&gt;&quot;&gt;
    &lt;span&gt;Number Of Units In Stock: &lt;%=Model.UnitsInStock %&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>
<p>And can be unit tested like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using AspNetMvcViewBestPractices.Helpers;
using NUnit.Framework;

namespace AspNetMvcViewBestPractices.Tests
{
    [TestFixture]
    public class ProductCssHelperTests
    {
        [Test]
        public void SelectCssClassForUnitsInStock_Returns_First_Css_Class_If_There_Are_No_Units_In_Stock()
        {
            // Arrange
            int unitsInStock = 0;

            // Act
            string cssClass = ProductCssHelper.SelectCssClassForUnitsInStock(unitsInStock,&quot;a&quot;,&quot;b&quot;,&quot;c&quot;);

            // Assert
            Assert.AreEqual(&quot;a&quot;, cssClass);
        }

        [Test]
        public void SelectCssClassForUnitsInStock_Returns_Second_Css_Class_If_Units_In_Stock_Is_Between_One_And_Twenty(
            [Range(1, 20)] int unitsInStock)
        {
            // Arrange        

            // Act
            string cssClass = ProductCssHelper.SelectCssClassForUnitsInStock(unitsInStock, &quot;a&quot;, &quot;b&quot;, &quot;c&quot;);

            // Assert
            Assert.AreEqual(&quot;b&quot;, cssClass);
        }

        [Test]
        public void SelectCssClassForUnitsInStock_Returns_Third_Css_Class_If_Units_In_Stock_Is_Over_Twenty()
        {
            // Arrange
            int unitsInStock = 21;

            // Act
            string cssClass = ProductCssHelper.SelectCssClassForUnitsInStock(unitsInStock, &quot;a&quot;, &quot;b&quot;, &quot;c&quot;);

            // Assert
            Assert.AreEqual(&quot;c&quot;, cssClass);
        }

        [Test]
        public void SelectCssClassForUnitsInStock_Returns_Empty_String_If_Units_In_Stock_Is_Less_Then_Zero()
        {
            // Arrange
            int unitsInStock = -1;

            // Act
            string cssClass = ProductCssHelper.SelectCssClassForUnitsInStock(unitsInStock, &quot;a&quot;, &quot;b&quot;, &quot;c&quot;);

            // Assert
            Assert.AreEqual(String.Empty, cssClass);
        }
    }
}
</pre>
<h3 class="subheading">Jag Reehal’s Final Thought on ‘ASP.NET MVC View Best Practices – Keep logic out of your views&#8217;</h3>
<p>I like my views to contain html but not logic so I prefer options 1, 3 and 4.  Because the html is hidden in option 2 finding out what method rendered what html could be like finding a needle in a haystack.  In addition the the unit tests for the html helper method are difficult to maintain as you have to check the entire html string is correct.</p>
<p>If you&#8217;re working with a designer you should choose option 4.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.arrangeactassert.com/asp-net-mvc-view-best-practices-keep-logic-out-of-your-views/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>ASP.NET MVC V2 and I met Scott Gu</title>
		<link>http://www.arrangeactassert.com/asp-net-mvc-v2-and-i-met-scott-gu/</link>
		<comments>http://www.arrangeactassert.com/asp-net-mvc-v2-and-i-met-scott-gu/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 07:56:41 +0000</pubDate>
		<dc:creator>Jag Reehal</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>

		<guid isPermaLink="false">http://www.arrangeactassert.com/?p=309</guid>
		<description><![CDATA[Lets get one thing out the way, yes I&#8217;m a geek, maybe not a super geek but a geek nevertheless. For me Scott Guthrie is up there with my Barca heroes Xavi, Iniesta Messi, Henry, Puyol, Valdés, Busquets, Krkić etc. Yesterday I went to Scott Gu&#8217;s demo of ASP.NET MVC 2 (using the preview 2 [...]]]></description>
			<content:encoded><![CDATA[<p>Lets get one thing out the way, yes I&#8217;m a geek, maybe not a super geek but a geek nevertheless.  For me Scott Guthrie is up there with my Barca heroes Xavi, Iniesta Messi, Henry, Puyol, Valdés, Busquets, Krkić etc.    </p>
<p>Yesterday I went to Scott Gu&#8217;s demo of ASP.NET MVC 2 (using the preview 2 release) in London and got to meet Mr ASP.NET MVC <img src='http://www.arrangeactassert.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><img src="http://www.arrangeactassert.com/wp-content/uploads/2009/10/Scott-Gu-and-Jag-Reehal.jpg" alt="Scott Gu and Jag Reehal" /></p>
<p>I&#8217;m not going to cover everything that’s coming in ASP.NET MVC 2 in any depth because <a href="http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx">Scott Gu</a>  and <a href="http://dotnetslackers.com/articles/aspnet/A-First-Look-at-ASP-NET-MVC-2.aspx">Ben Scheirman&#8217; First Look at ASP.NET MVC 2</a> do a good job of that. </p>
<p>It&#8217;s interesting to see that Microsoft is taking rapid web development and templating so seriously.  Using the new UI helpers you can create html for labels, inputs and validation with just one line of code in your view instead of three.</p>
<p>This will save you time and mean there is less chance of having any html typos.  It will also make it easier to refactor because everything is strongly typed!  If you wanted to do this now you could create an html helper extension.  </p>
<p>What you can’t do now (not easily anyway) is just have the UI helpers create the label, input and validation for an entire model with one line of code.  This will save you even more time and means you don&#8217;t have to manually edit html in views just because you have added new properties to your view model.  </p>
<p>Amazing I think you will agree, however I can&#8217;t help thinking it&#8217;s not going to be testable and could potentially lead to inadvertently displaying something you didn&#8217;t want to show.</p>
<p>Scott also showed how to use System.ComponentModel.DataAnnotations for validation and the client side validation which uses the jQuery validation framework.  If you want that functionality now checkout Steve Sanderson’s excellent <a href="http://blog.codeville.net/2009/09/17/xval-v10-now-available">xVal framework</a>.</p>
<p>I asked Scott if there was a possibility of not having &#8216;magic strings&#8217; in action links and the render partial methods.  He said they were working on it, so hopefully we could see something in preview 3.  </p>
<p>As for release dates, Scott Gu suggested ASP.NET MVC 2 should be ready early next year.</p>
<p>I have no doubt that ASP.NET MVC 2 will make it even better to develop web sites with.</p>
<p>If you want to see a recording of <a href="http://channel9.msdn.com/posts/matthijs/Scott-Guthrie-ASPNET-MVC-2/">Scott Guthrie talking about ASP.NET MVC 2 it’s available on Channel 9</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.arrangeactassert.com/asp-net-mvc-v2-and-i-met-scott-gu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ASP.NET MVC Controller Best Practices – Skinny Controllers</title>
		<link>http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%e2%80%93-skinny-controllers/</link>
		<comments>http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%e2%80%93-skinny-controllers/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 20:40:32 +0000</pubDate>
		<dc:creator>Jag Reehal</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[Unit tests]]></category>

		<guid isPermaLink="false">http://www.arrangeactassert.com/?p=285</guid>
		<description><![CDATA[No blog post can cover ASP.NET MVC controller best practices in one go. So this is the first post in a series about ASP.NET MVC controller best practices. In this post we&#8217;re looking at why your ASP.NET MVC controllers should be &#8216;skinny&#8217;. The code used in this post can be downloaded here. I’ve heard Jeffrey [...]]]></description>
			<content:encoded><![CDATA[<p>No blog post can cover ASP.NET MVC controller best practices in one go.  So this is the first post in a series about ASP.NET MVC controller best practices.  </p>
<p>In this post we&#8217;re looking at why your ASP.NET MVC controllers should be &#8216;skinny&#8217;.    </p>
<p>The code used in this post can be downloaded <a href="http://www.arrangeactassert.com/wp-content/themes/resources/Code/TestingMvcControllers.zip">here</a>.  </p>
<p>I’ve heard Jeffrey Palermo say if you can’t see a ASP.NET MVC action method on a screen without having to scroll, you have a problem.  In most cases the problem is the controller has multiple responsibilities. </p>
<p>The code in this post is adapted from a code sample I saw in an ASP.NET MVC book.</p>
<p>The controller looks like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using System.Linq;
using System.Web.Mvc;
using TestingMvcControllers.Interfaces;
using TestingMvcControllers.Models;

namespace TestingMvcControllers.Controllers
{
    public class AnimalsController : Controller
    {
        public int PageSize = 4;
        private readonly IAnimalsRepository _animalsRepository;

        public AnimalsController(IAnimalsRepository animalsRepository)
        {
            _animalsRepository = animalsRepository;
        }

        public ViewResult List(string category, int page)
        {
            var animalsInCategory = (category == null)
                                        ? _animalsRepository.Animals
                                        : _animalsRepository.Animals.Where(x =&gt; x.Category == category);

            int numberOfAnimals = animalsInCategory.Count();
            ViewData[&quot;TotalPages&quot;] = (int)Math.Ceiling((double)numberOfAnimals / PageSize);
            ViewData[&quot;CurrentPage&quot;] = page;
            ViewData[&quot;CurrentCategory&quot;] = category;

            return View(animalsInCategory
                            .Skip((page - 1) * PageSize)
                            .Take(PageSize)
                            .ToList()
                );
        }
    }
}
</pre>
<p>This approach will work, but what if you wanted to implement paging for another user interface? You would not be able to reuse the paging functionality in the controller and have to repeat yourself.  This goes against the<a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"> ‘Don&#8217;t Repeat Yourself (DRY)</a> principle.</p>
<p>At this point some of you maybe be saying <a href="http://en.wikipedia.org/wiki/YAGNI">you ain&#8217;t gonna need it (YAGNI)</a>.  Maybe&#8230; but let’s have a look at impact paging logic in the controller has when it comes to the unit testing the ASP.NET MVC controller.</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System.Collections.Generic;
using NUnit.Framework;
using Rhino.Mocks;
using TestingMvcControllers.Controllers;
using TestingMvcControllers.Interfaces;
using TestingMvcControllers.Models;

namespace TestingMvcControllers.Tests
{
    [TestFixture]
    public class AnimalsControllerTests
    {
        private IAnimalsRepository _animalsRepository;
        private AnimalsController _controller;

        [SetUp]
        public void SetUp()
        {
            _animalsRepository = MockRepository.GenerateStub&lt;IAnimalsRepository&gt;();
            _controller = new AnimalsController(_animalsRepository);
        }

        [Test]
        public void List_Presents_Correct_Page_Of_Animals()
        {
            // Arrange
            _controller.PageSize = 3;

            // Act
            _animalsRepository.Stub(a =&gt; a.Animals).Return(AnimalsStub.Animals);
            var result = _controller.List(null, 2);

            // Assert
            Assert.IsNotNull(result, &quot;Didn't render view&quot;);
            var Animals = result.ViewData.Model as IList&lt;Animal&gt;;
            Assert.AreEqual(2, Animals.Count, &quot;Got wrong number of animals&quot;);
            Assert.AreEqual(2, (int)result.ViewData[&quot;CurrentPage&quot;], &quot;Page number was wrong&quot;);
            Assert.AreEqual(2, (int)result.ViewData[&quot;TotalPages&quot;], &quot;Page count was wrong&quot;);
            Assert.AreEqual(&quot;Iguana&quot;, Animals[0].Name);
            Assert.AreEqual(&quot;Loin&quot;, Animals[1].Name);
        }

        [Test]
        public void List_Includes_All_Animals_When_Category_Is_Null()
        {
            // Arrange
            _controller.PageSize = 10;            

            // Act
            _animalsRepository.Stub(a =&gt; a.Animals).Return(AnimalsStub.Animals);
            var result = _controller.List(null, 1);

            // Assert
            Assert.IsNotNull(result, &quot;Didn't render view&quot;);
            var Animals = (IList&lt;Animal&gt;)result.ViewData.Model;
            Assert.AreEqual(5, Animals.Count, &quot;Should have got 5 animals&quot;);
        }

        [Test]
        public void List_Filters_By_Category_When_Requested()
        {
            // Arrnage
            _controller.PageSize = 10;

            // Act
            _animalsRepository.Stub(a =&gt; a.Animals).Return(AnimalsStub.Animals);
            var result = _controller.List(&quot;Reptile&quot;, 1);

            // Assert
            Assert.IsNotNull(result, &quot;Didn't render view&quot;);
            var Animals = (IList&lt;Animal&gt;)result.ViewData.Model;
            Assert.AreEqual(3, Animals.Count, &quot;Should have got 3 animals&quot;);
            Assert.AreEqual(&quot;Crocodile&quot;, Animals[0].Name);
            Assert.AreEqual(&quot;Snake&quot;, Animals[1].Name);
            Assert.AreEqual(&quot;Iguana&quot;, Animals[2].Name);
            Assert.AreEqual(&quot;Reptile&quot;, result.ViewData[&quot;CurrentCategory&quot;]);
        }
    }
}
</pre>
<p>Because the controller is also responsible for paging, you have to write unit tests for paging logic on top of the unit tests you should be writing for the controller.  This means you will either ending up not testing enough and/or too much and find the tests a nightmare to maintain in the future.  See my post about <a href="http://www.arrangeactassert.com/how-to-unit-test-asp-net-mvc-controllers/">How to Unit Test ASP.NET MVC Controllers</a>.</p>
<h3 class="subheading">How I would refactor</h3>
<p>I would move the paging functionality into a new layer.  Yes I know adding another layer is always the solution to any problem in software development <img src='http://www.arrangeactassert.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   </p>
<p>The animal service layer looks like this</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System;
using System.Linq;
using TestingMvcControllers.Interfaces;
using TestingMvcControllers.Models;

namespace TestingMvcControllers.Services
{
    public class AnimalsService : IAnimalsService
    {
        private readonly IAnimalsRepository _animalsRepository;
        public int PageSize = 4;

        public AnimalsService(IAnimalsRepository animalsRepository)
        {
            _animalsRepository = animalsRepository;
        }

        public AnimalsDto GetAnimals(string category, int page)
        {
            AnimalsDto animalsDto = new AnimalsDto();

            var animalsInCategory =  (category == null)
                            ? _animalsRepository.Animals
                            : _animalsRepository.Animals.Where(x =&gt; x.Category == category);

            int numberOfAnimals = animalsInCategory.Count();
            animalsDto.CurrentCategory = category;
            animalsDto.CurrentPage = page;
            animalsDto.TotalPages = (int)Math.Ceiling((double)numberOfAnimals / PageSize);
            animalsDto.Animals = animalsInCategory
                .Skip((page - 1)*PageSize)
                .Take(PageSize)
                .ToList();

            return animalsDto;
        }
    }
}
</pre>
<p>Notice how a ‘Dto’ object is returned from the service.  While this should be done using an <a href="http://www.codeplex.com/AutoMapper">AutoMapper</a>, it’s not the focus of this test.  The total number of pages can now be returned to the view as part of the model, rather than as a dictionary entry in ViewData.</p>
<p>The controller now looks clean and simple</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using System.Web.Mvc;
using TestingMvcControllers.Interfaces;

namespace TestingMvcControllers.Controllers
{
    public class BetterAnimalsController : Controller
    {
        private readonly IAnimalsService _animalsService;

        public BetterAnimalsController(IAnimalsService animalsService)
        {
            _animalsService = animalsService;
        }

        public ViewResult List(string category, int page)
        {
            var animalsDto = _animalsService.GetAnimals(category, page);
            return View(&quot;List&quot;,animalsDto);
        }
    }
}
</pre>
<p>The unit tests for the controller are about testing the controller and nothing more!</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
using MvcContrib.TestHelper;
using NUnit.Framework;
using Rhino.Mocks;
using TestingMvcControllers.Controllers;
using TestingMvcControllers.Interfaces;
using TestingMvcControllers.Models;

namespace TestingMvcControllers.Tests
{
    [TestFixture]
    public class BetterAnimalsControllerTests
    {
        private IAnimalsService _animalsService;
        private BetterAnimalsController _controller;

        [SetUp]
        public void SetUp()
        {
            _animalsService = MockRepository.GenerateStub&lt;IAnimalsService&gt;();
            _controller = new BetterAnimalsController(_animalsService);
        }

        [Test]
        public void The_List_Action_Returns_AnimalsDto_To_The_View()
        {
            // Arrange
            _animalsService.Stub(a =&gt; a.GetAnimals(null,0))
                .IgnoreArguments()
                .Return(new AnimalsDto());

            // Act
            var result = _controller.List(null, 0);

            // Assert
            result.AssertViewRendered().WithViewData&lt;AnimalsDto&gt;();
        }

        [Test]
        public void The_List_Action_Returns_List_View()
        {
            // Arrange
            _animalsService.Stub(a =&gt; a.GetAnimals(null, 0))
                .IgnoreArguments()
                .Return(new AnimalsDto());

            // Act
            var result = _controller.List(null, 0);

            // Assert
            result.AssertViewRendered().ForView(&quot;List&quot;);
        }
    }
}
</pre>
<h3 class="subheading">Jag Reehal’s Final Thought on ‘Skinny ASP.NET MVC Controllers’ </h3>
<p>There is of course more than one way to skin a cat.  This solution could have been refactored in many different ways.  </p>
<p>The refactoring done in the post means:</p>
<ul>
<li>The ASP.NET MVC controller is skinnier with less responsibility which means it’s easier to read and maintain</li>
<li>The controller unit tests can focus on the &#8216;subject under test&#8217;</li>
<li>The paging functionality can be used by multiple user interfaces</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%e2%80%93-skinny-controllers/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How to Unit Test ASP.NET MVC Controllers</title>
		<link>http://www.arrangeactassert.com/how-to-unit-test-asp-net-mvc-controllers/</link>
		<comments>http://www.arrangeactassert.com/how-to-unit-test-asp-net-mvc-controllers/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 22:48:57 +0000</pubDate>
		<dc:creator>Jag Reehal</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[Unit tests]]></category>

		<guid isPermaLink="false">http://www.arrangeactassert.com/?p=250</guid>
		<description><![CDATA[Given one of the major advantages ASP.NET MVC has over traditional ASP.NET web forms is testability, it&#8217;s surprising how many code samples in books and on the web don’t cover how to unit test controllers. There are also many examples of unit tests for ASP.NET MVC controllers that don&#8217;t do enough, or do to much. [...]]]></description>
			<content:encoded><![CDATA[<p>Given one of the major advantages ASP.NET MVC has over traditional ASP.NET web forms is testability, it&#8217;s surprising how many code samples in books and on the web don’t cover how to unit test controllers.  There are also many examples of unit tests for ASP.NET MVC controllers that don&#8217;t do enough, or do to much.</p>
<p>I want to show examples of good unit tests for ASP.NET MVC controllers and what to avoid so you don&#8217;t end up testing more than you should.  </p>
<p>The code used in this post can be downloaded <a href="http://cid-8a29bf85dc9538dc.skydrive.live.com/self.aspx/.Public/TestingMvcControllers.zip">here</a>. </p>
<p>Let me start off by discussing what types of unit tests you should be creating for MVC controllers.</p>
<ul>
<li> Tests to check the correct action result is returned from a controller action.  This includes information about the action result, such as the testing the correct view is returned for a view result.</li>
<li>Tests to check if the view model is what you expected.  If you have a strongly typed view which expects class foo and you pass class bar to your view model, your code will compile, would result in a runtime error like the one shown below.</li>
</ul>
<p><img title="ASP NET MVC Runtime Error" src="http://www.arrangeactassert.com/wp-content/uploads/2009/09/ASP-NET-MVC-Runtime-Error.jpg" alt="ASP NET MVC Runtime Error" width="650" height="87" /></p>
<p>If you are testing anything more than this your controller is doing too much.  One of the fundamental design practices for MVC controllers is too have skinny controllers.  You should you should be able to view a controller method without having to scroll.  This will be the focus of my next blog.  On that subject you will notice examples in this post don&#8217;t include action filters, I think they should be tested separately and is something for a future blog post.  </p>
<p>In the unit tests examples below you will see one version using the <a href="http://mvccontrib.codeplex.com/Wiki/View.aspx?title=TestHelper">MvcContrib.TestHelper</a> assembly, and another without it.  I can&#8217;t recommend this enough because it saves you from writing as many extension methods and test helpers in tests to keep you code clean, readable and maintainable.  This is even more important when it comes to doing test driven development because it allows you to concentrate on writing better unit tests without having write more lines of code than you need to.</p>
<p>Also notice how I create a variable for the expected view and route names for the unit tests not using the MvcContrib.TestHelper.  Now if I decide to rename the view or route name I only have to change the code in one place.    </p>
<p>If you&#8217;re new to mocking frameworks and stubs, check out my <a href="http://www.arrangeactassert.com/how-to-write-better-unit-tests-using-rhinomocks-and-stubs/">beginners guide to mocking frameworks</a>. </p>
<h3 class="subheading">Unit tests to check an ASP.NET MVC controller returns the correct view</h3>
<p>When a controller has no conditional logic i.e. single code path that only returns a single action result, the unit test is straightforward.  </p>
<p>Controller Action:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
public ActionResult Index()
{
    return View(&quot;Index&quot;);
}
</pre>
<p>Unit Test:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
[Test]
public void Default_Action_Returns_Index_View()
{
    // Arrange
    const string expectedViewName = &quot;Index&quot;;
    var customersController = new CustomerController(null);

    // Act
    var result = customersController.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result, &quot;Should have returned a ViewResult&quot;);
    Assert.AreEqual(expectedViewName, result.ViewName, &quot;View name should have been {0}&quot;, expectedViewName);
}

[Test]
public void Default_Action_Returns_Index_View_Using_MvcContrib_TestHelper()
{
    // Arrange
    var customersController = new CustomerController(null);

    // Act
    var result = customersController.Index();

    // Assert
    result.AssertViewRendered().ForView(&quot;Index&quot;);
}
</pre>
<h3 class="subheading">Unit tests to check an ASP.NET MVC controller sets ViewData (and TempData) values</h3>
<p>Testing if a controller sets ViewData or TempData values is simple enough.  In the example below the page number and page size are passed to the controller, but need to be passed back to the view.  Afterall ASP.NET MVC web sites should to be stateless.  In another blog post where controller best practices will be covered, I’ll show you how and why details such as the page number and page size should be properties in the model passed to the view, rather than as ViewData dictionary values and entering magic string territory.  </p>
<p>Controller Action:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
public ViewResult List(int? pageNumber, int? pageSize)
{
    IList&lt;Customer&gt; customers = _customerService.Get(pageNumber, pageSize);

    ViewData[&quot;PageNumber&quot;] = pageNumber;
    ViewData[&quot;PageSize&quot;] = pageSize;

    return View(&quot;List&quot;, customers);
}
</pre>
<p>Unit Test:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
[Test]
public void The_List_Action_Returns_The_Page_Number_And_Size_In_ViewData()
{
    // Arrange
    const int pageNumber = 1;
    const int pageSize = 10;
    var customerService = MockRepository.GenerateStub&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);

    // Act
    var result = customersController.List(pageNumber, pageSize);

    // Assert
    Assert.AreEqual(pageNumber, result.ViewData[&quot;pageNumber&quot;], &quot;Page Number Was Incorrect&quot;);
    Assert.AreEqual(pageSize, result.ViewData[&quot;pageSize&quot;], &quot;Page Size Was Incorrect&quot;);
}
</pre>
<h3 class="subheading">Unit tests to check an ASP.NET MVC controller returns the correct type of object to a strongly typed view model</h3>
<p>It’s good practice to use strong typed views so you need to ensure the MVC controller returns the model the view is expecting.   Once written this unit test can be a useful regression test just in case a colleague changes what model a controller passes to a view.</p>
<p>Controller Action:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
public ViewResult List(int? pageNumber, int? pageSize)
{
    IList&lt;Customer&gt; customers = _customerService.Get(pageNumber, pageSize);

    ViewData[&quot;PageNumber&quot;] = pageNumber;
    ViewData[&quot;PageSize&quot;] = pageSize;

    return View(&quot;List&quot;, customers);
}
</pre>
<p>Unit Test:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
[Test]
public void The_List_Action_Returns_IList_Customers_To_The_View()
{
    // Arrange
    var customerService = MockRepository.GenerateStub&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);

    // Set up result for customers service
    customerService.Stub(c =&gt; c.Get(null, null))
        .IgnoreArguments()
        .Return(new List&lt;Customer&gt;());

    // Act
    var result = customersController.List(null, null);

    // Assert
    var model = result.ViewData.Model as IList&lt;Customer&gt;;
    Assert.IsNotNull(model, &quot;Model should have been type of IList&lt;Customer&gt;&quot;);
}

[Test]
public void The_List_Action_Returns_IList_Customers_To_The_View_Using_MvcContrib_TestHelper()
{
    // Arrange
    var customerService = MockRepository.GenerateStub&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);

    // Set up result for customers service
    customerService.Stub(c =&gt; c.Get(null, null))
        .IgnoreArguments()
        .Return(new List&lt;Customer&gt;());

    // Act
    var result = customersController.List(null, null);

    // Assert
    result.AssertViewRendered().WithViewData&lt;IList&lt;Customer&gt;&gt;();
}
</pre>
<h3 class="subheading">Unit tests to check an ASP.NET MVC controller returns the expected action result depending on the model state e.g. unit testing the Post-Redirect-Get pattern</h3>
<p>When validating a users input you want your controller to return the appropriate action result depending the model state.  For this you should follow the <a href="http://en.wikipedia.org/wiki/Post/Redirect/Get">Post-Redirect-Get</a> pattern where a valid form submission results in a RedirectToRouteResult, and an invalid form submission should return a ViewResult.  The example below shows how to unit test the Post-Redirect-Get pattern for a MVC controller.  </p>
<p>Pay attention to how you can add an error to the model state collection.  This means you don’t have to worry about what makes a model invalid. </p>
<p>However to ensure you pass in a valid model I would use a test stub which could be used whenever you need an instance of a valid model.  </p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
public ActionResult Create(Customer customer)
{
    if (ModelState.IsValid)
    {
        _customerService.Save(customer);
        return RedirectToRoute(&quot;CustomerCreated&quot;);
    }
    return View(&quot;Create&quot;, customer);
}
</pre>
<p>Unit Tests:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
[Test]
public void The_Add_Customer_Action_Returns_RedirectToRouteResult_When_The_Customer_Model_Is_Valid()
{
    // Arrange
    const string expectedRouteName = &quot;CustomerCreated&quot;;
    var customer = CustomerStub.ValidCustomer;
    var customerService = MockRepository.GenerateStub&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);

    // Act
    var result = customersController.Create(customer) as RedirectToRouteResult;

    // Assert
    Assert.IsNotNull(result, &quot;Should have returned a RedirectToRouteResult&quot;);
    Assert.AreEqual(expectedRouteName, result.RouteName, &quot;Route name should have been {0}&quot;, expectedRouteName);

}

[Test]
public void The_Add_Customer_Action_Returns_RedirectToRouteResult_When_The_Customer_Model_Is_Valid_Using_MvcContrib_TestHelper()
{
    // Arrange
    var customer = CustomerStub.ValidCustomer;
    var customerService = MockRepository.GenerateStub&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);

    // Act
    var result = customersController.Create(customer);

    // Assert
    result.AssertActionRedirect().RouteName.ShouldBe(&quot;CustomerCreated&quot;);
}

[Test]
public void The_Add_Customer_Action_Returns_ViewResult_When_The_Customer_Model_Is_Invalid()
{
    // Arrange
    const string expectedViewName = &quot;Create&quot;;
    var customer = new Customer();
    var customerService = MockRepository.GenerateStub&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);
    customersController.ModelState.AddModelError(&quot;A Error&quot;, &quot;Message&quot;);

    // Act
    var result = customersController.Create(customer) as ViewResult;

    // Assert
    Assert.IsNotNull(result, &quot;Should have returned a ViewResult&quot;);
    Assert.AreEqual(expectedViewName, result.ViewName, &quot;View name should have been {0}&quot;, expectedViewName);
}

[Test]
public void The_Add_Customer_Action_Returns_ViewResult_When_The_Customer_Model_Is_Invalid_Using_MvcContrib_TestHelper()
{
    // Arrange
    var customer = new Customer();
    var customerService = MockRepository.GenerateStub&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);
    customersController.ModelState.AddModelError(&quot;A Error&quot;, &quot;Message&quot;);

    // Act
    var result = customersController.Create(customer);

    // Assert
    result.AssertViewRendered().ViewName.ShouldBe(&quot;Create&quot;);
}
</pre>
<h3 class="subheading">Behaviour tests for ASP.NET MVC controllers</h3>
<p>So far I have only covered state based testing.  You can write unit tests for your controller to check if a methods was called.  For example when a valid model has been passed to a controller the save method should be called.  However when an invalid model is passed to a controller the save method should not be called.</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
public ActionResult Create(Customer customer)
{
    if (ModelState.IsValid)
    {
        _customerService.Save(customer);
        return RedirectToRoute(&quot;CustomerCreated&quot;);
    }
    return View(&quot;Create&quot;, customer);
}
</pre>
<p>Unit Tests:</p>
<pre class="brush: csharp; gutter: false; toolbar: true;">
[Test]
public void The_CustomerService_Save_Method_Is_Called_When_The_Customer_Model_Is_Valid()
{
    // Arrange
    var customer = CustomerStub.ValidCustomer;
    var customerService = MockRepository.GenerateMock&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);

    // Act
    customersController.Create(customer);

    // Assert
    customerService.AssertWasCalled(c =&gt; c.Save(customer));
}

[Test]
public void The_CustomerService_Save_Method_Is_NOT_Called_When_The_Customer_Model_Is_Invalid()
{
    // Arrange
    var customer = new Customer();
    var customerService = MockRepository.GenerateMock&lt;ICustomerService&gt;();
    var customersController = new CustomerController(customerService);
    customersController.ModelState.AddModelError(&quot;A Error&quot;, &quot;Message&quot;);

    // Act
    customersController.Create(customer);

    // Assert
    customerService.AssertWasNotCalled(c =&gt; c.Save(customer));
}
</pre>
<h3 class="subheading">Jag Reehal’s Final Thought on &#8216;How to Unit Test ASP.NET MVC Controllers&#8217;</h3>
<p>Hopefully you can use the examples I&#8217;ve shown here as templates for your ASP.NET MVC controller unit tests.  </p>
<p>You can of course combine the tests above and have multiple assertions such as testing the view name and view model in a single test.  Just be aware unit test best practices say you should only have one assertion per test.  If you have multiple assertions just make sure you output a message for each assertion.  This way  you will know which assertion failed, like in the example for testing view data above.  </p>
<p>Check out my post about <a href="http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-–-skinny-controllers/">ASP.NET MVC best practices</a> for more examples on good ASP.NET MVC controller unit tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.arrangeactassert.com/how-to-unit-test-asp-net-mvc-controllers/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
