Shane Bauer Blog
.NET, ASP.NET and Software Development

Using MvcContrib's TestControllerBuilder to Test Your ASP.NET MVC Controllers

April 14, 2008 06:40 by sbauer

One benefit of ASP.NET MVC (or any MVC framework) is the ability to test your code without having to start up a web server. Sure, you could have always unit tested your model layer, but what if you wanted to ensure that your web application code was interacting correctly with your domain?

A Quick Scenario

Lets say, for example, you have an Article controller. The controller has an action called "view". This action accepts one parameter, an integer, representing the article ID. The action code would then take the ID, and query the database for the article record. What happens if it doesn't find a record? Obviously, you could do any number of things. You could redirect them to a not found action or just display a different view. To keep things simple in this example, we'll just redirect the user to the main article page.

Controllers are Test-Friendly, kind of

As I said above, a benefit of the MVC framework is the ability to test your code without having to bother with ugly hacks to manipulate a web server and/or the ASP.NET pipeline. The ASP.NET MVC is an improvement in this area without a doubt. However, it's not perfect. There are areas in which you cannot test easily. RedirectData, for example, is one example of something that's difficult to test. There are ways to work around this limitation, but they are exactly that: a work-around. Fortunately, the MVC team has recognized a few areas that could be improved and are actively addressing our concerns for the next preview. 

Introducing the TestControllerBuilder

The MvcContrib project is an open source project that boasts quite a few additional features you can add to your project. For example, MvcContrib offers a variety of controller factories that integrate will all of the major IoC containers. In addition, MvcContrib also has a collection of view engines you can use if you're not satisfied with the WebForms view engine that's enabled by default.

The TestControllerBuilder is another contribution that's also available in this project. TestControllerBuilder uses a dynamic proxy and an interceptor to relieve some of the pain behind controller testing. Below is a sample test using the TestControllerBuilder, Rhino Mocks and MbUnit. In order for this to work, I need to make sure my mock instance of IArticleService returns a null instance. I'm using Rhino Mocks "SetupResult" for this.

 

[Test]
public void Unknown_Article_Redirects_To_Index()
{
TestControllerBuilder builder = new TestControllerBuilder();
ArticleController controller = builder.CreateController<ArticleController>(new object[] { articleService });
SetupResult.For(articleService.GetArticle(1)).IgnoreArguments().Return(null);
controller.View(1);
Assert.AreEqual(builder.RedirectToActionData.ActionName, "index");
}

 

Now, here's the action implementation.

public void View(int id)
{
    Article article = articleService.GetArticle(id);
    if (article == null)
        RedirectToAction("index");
    ArticleControllerViewData viewData = new ArticleControllerViewData {Article = article};         
    RenderView("view", viewData);
}
 

Changes are Coming

As I mentioned above, changes are coming. I'm not sure how long this code will be appropriate (hopefully not long). Either way, I thought it was worth mentioning. 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.NET MVC
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Related posts

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

January 5. 2009 21:51