# Thursday, 01 December 2011

The Test Helpers are a great way to ease your testing needs with MVC.  If your using the Test Helpers to test your routing like so:

            "~/".ShouldMapTo<HomeController>(x => x.Index());

When you run your tests you’ll get the following error:

System.Security.VerificationException : Method MvcContrib.TestHelper.RouteTestingExtensions.ShouldMapTo: type argument 'Your Controller Name’ violates the constraint of type parameter 'TController'.

The fix is a binding direct.

Add an app.config to your test project and paste in the following:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="4.0.0.0" />
        </dependentAssembly>
    </assemblyBinding>
</runtime>

Happy Coding! Smile

Posted 12.01.2011  #    Comments [7]  | 
# Friday, 05 March 2010

Want to learn ASP.Net MVC?  Perhaps you already started learning it.  I decided to take a side project of mine that I started in Web Forms and completely start over with .Net MVC.  I wanted to document what I did and the resources I found in the hopes that it may help you.  I still have much to learn and master with .Net MVC but so far I am impressed and am happy I decided to branch out and learn something new.  It has made me a better developer and a more well informed developer.  Both good things!

Not sure what ASP.Net MVC is?  Check out this intro video and this overview and then hurry on back.

How I started:

ASP.Net MVC Tutorials and many, many blog posts from Scott Guthrie, Phil Haack, Rob Conery, Jimmy Bogard, Jeffrey Palermo, Eric Hexter, Steven Sanderson, Stephen Walther and these are just the ones I remember.

Books:

I started with ASP.Net MVC In Action and quickly realized that many of it’s topic were over my head.  So I put it down and read ASP.Net MVC Framework Unleashed and Pro ASP.Net MVC Framework and then went back to MVC In Action. 

TIP #1 - When I am learning a new technology I tend to do the examples in the book from scratch.  It takes longer than just downloading their sample code but it helps me absorb it more. 

TIP #2 – Almost all the material I read on ASP.Net MVC touch on or go into detail on Unit Testing, Test Driven Development, Dependency Injection, Inversion Of Control and many other design principles.  If you are not sure what these are you might want to research them a little bit.  The books I recommend do give overviews of these.  One of MVC’s main design goals is for giving control of the application back to the developer and ease of testing.  If you find this even the least bit interesting then keep going!

Samples/Tutorials:

ASP.Net MVC Tutorials – I watched these to get a feel for MVC.  They have a lot of video’s and sample code you can run through.  They did a great job of covering the basics.  Stay here a while, fire up your IDE and peck away on the keyboard with these tutorials.

Nerd Dinner – Perhaps a cult classic or a right of passage?  I for the most part skipped it…. Oooppsss.  No wonder I struggled so hard with MVC in the beginning.  Just kidding.    It was one of the first books and sample apps out.  I skipped it only because I didn’t have it in my Safari Books Online.  I did however take advantage of their free chapter and source code.

Rob Conery – Rob Conery published a set of video’s documenting the development of an eCommerce storefront called MVC StoreFront.  I watched these video’s carefully and read his code carefully.  He then renamed the project to Kona and added a few more screencasts.  Check these out.  I poured through his code to see some of the possibilities that MVC has.  I still don’t understand some of it but Rob’s a much smarter guy than I am. :-)

Starter kits – Check out their Northwind MVC project, period.

Tip #3 – Check out the ASP.Net MVC Tutorials and the MVC storefront screencasts at least! 

Cheat sheets – Elijah Manor published several cheat sheets on MVC that are great to put on your wall or at least keep close at hand while you are learning MVC.

50 ASP.Net MVC Tips – Stephen Walther, author of ASP.Net MVC Framework Unleashed published these nice tips on his blog.

MVC Contrib Project – A bit more advanced but the wizards over at Headspring created this little open source gem.  The ASP.Net MVC In Action’s sample project uses MVC Contrib.  The project is great and I am still digesting a lot of what is in the project.  I especially dig the TestHelper library.  It just makes my job of testing routes a breeze.

I mentioned I used a side project to learn ASP.Net MVC.  I know now that had I not done that I would still be sitting here thinking about learning it.  Why?  I found many things I took for granted with Web Forms were gone in ASP.Net MVC.  Viewstate for example.  I had certainly grown accustom to it.  Another gotcha for me was filling a dropdown list the right way (not directly in the controller).  I truly did have some frustrating points with ASP.Net MVC but only because I had to retrain myself to how the internet really works (Web Forms took care of this for me).  I really am better for it now.  

Tip #4 – Take a tangible project and do it in ASP.Net MVC.  Stick with it.  It is very different from Web Forms if this is where you are coming from.  Please read my post on Confessions of a Web Form Guy Learning ASP.Net MVC if you want a little insight into some of the "aha" moments I had. 

MVC is moving fast, as of this writing they are already on of MVC2 RC2.  A lot of new features are coming our way that make MVC that much sweeter. 

I hope this helps you in your journey!  If you know of some other good resources for ASP.Net MVC please comment on it.

Happy Coding!

Posted 03.05.2010  #    Comments [0]  | 
# Saturday, 12 December 2009

Testing the routes in .Net MVC can be a bit tedious without some help.  MVCContrib’s TestHelper library eases the load and makes testing routes a breeze.

To demonstrate, I created an application to manage recipes with their ingredients and directions. Below is how I wanted the routing to work.

What I want the URL to look like What it will do
/recipe List all recipes
/recipe/blueberrypie Display blueberry pie recipe
/recipe/edit/blueberrypie Edit blueberry pie recipe
/recipe/blueberrypie/ingredients Show the ingredients for blueberry pie
/recipe/blueberrypie/directions Show directions for blueberry pie
/recipe/blueberrypie/ingredients/delete/1234 Delete ingredient with ID 1234 for blueberry pie & go back to the list of ingredients

I edited the RegisterRoutes method in the Global.asax.cs file to match the table:

// recipe/BlueberryPie/ingredients/edit/1234
routes.MapRoute(
    "Ingredients",
    "recipe/{nameKey}/ingredients/{action}/{id}",
    new { controller = "Ingredients", action = "Index" },
    new { id = @"\d+" }
    );

// recipe/BlueberryPie/ingredients/
routes.MapRoute(
    "IngredientsForRecipe",
    "recipe/{nameKey}/ingredients/{action}",
    new { controller = "Ingredients", action = "List" }
    );

// recipe/BlueberryPie/directions/edit/1234
routes.MapRoute(
    "Directions",
    "recipe/{nameKey}/directions/{action}/{id}",
    new { controller = "directions", action = "Index" },
    new { id = @"\d+" }
    );

// recipe/BlueberryPie/directions/
routes.MapRoute(
    "DirectionsForRecipe",
    "recipe/{nameKey}/directions/{action}",
    new { controller = "directions", action = "List" }
    );

// recipe/edit/BlueberryPie
routes.MapRoute(
    null,
    "recipe/{action}/{nameKey}",
    new { controller = "Recipe", action = "List", nameKey = "" },
    new { action = "create|edit|index|list" }
    );

// recipe/BlueberryPie
routes.MapRoute(
    "recipe",
    "recipe/{nameKey}",
     new { controller = "Recipe", action = "Index" }
    );

Now for the magic with MVCContrib’s TestHelper library and the extension ShouldMapTo:

[TestFixture]
public class RouteTests
{
    [TestFixtureSetUp]
    public void SetUp()
    {
        RouteTable.Routes.Clear();
        MvcApplication.RegisterRoutes(RouteTable.Routes); 
    }

    [Test]
    public void RootMatchesHome()
    {
        "~/".ShouldMapTo(x => x.Index());
    }

    [Test]
    public void RecipeRootMatchesList()
    {
        "~/recipe".ShouldMapTo(x => x.List());
    }

    [Test]
    public void RecipeNameShouldDisplayIndex()
    {
        "~/recipe/BlueberryPie".ShouldMapTo(x => x.Index("BlueberryPie")); 
    }

    [Test]
    public void CreateRecipeShouldDisplayCreateAction()
    {
        "~/recipe/create/".ShouldMapTo(x => x.Create());
    }

    [Test]
    public void EditRecipeShouldDisplayEditAction()
    {
        "~/recipe/edit/BlueberryPie".ShouldMapTo(x => x.Edit("BlueberryPie"));
    }
    [Test]
    public void DeleteRecipeShouldDisplayDeleteAction()
    {
        "~/recipe/delete/1".ShouldMapTo(x => x.Delete(1));
    }
    [Test]
    public void IngredientsForRecipeShouldDisplayIngredientsListAction()
    {
        "~/recipe/BlueberryPie/ingredients".ShouldMapTo(i => i.List("BlueberryPie")); 
    }
    [Test]
    public void DirectionsForRecipeShouldDisplayIngredientsListAction()
    {
        "~/recipe/BlueberryPie/directions".ShouldMapTo(i => i.List("BlueberryPie"));
    }
    [Test]
    public void DeleteIngredientShouldDisplayDeleteAction()
    {
        "~/recipe/BlueberryPie/ingredients/delete/1".ShouldMapTo(i => i.Delete(1));
    }
    [Test]
    public void DeleteDirectionShouldDisplayDeleteAction()
    {
        "~/recipe/BlueberryPie/directions/delete/1".ShouldMapTo(i => i.Delete(1));
    }
}

No need to mock/fake any context, setup route data, etc.  The code is short and sweet, easy to read, understand and matches the URL that would be in the browser making it very intuitive.

Please download the code.  The sample is using NUnit 2.5.

MVCContribTestRoutes.zip (603.49 KB)

Happy coding!

Posted 12.12.2009  #    Comments [0]  |