CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo [MVP]

Software management consultant and CTO, Headspring Systems

So much easier to test plain ASP.NET MVC controllers!!

I was having a hard time easily testing controller classes with the MVC Framework December CTP.  Now it's easier.  For some background, I'm writing ASP.NET MVC in Action for Manning, so I'm going through all kinds of scenarios, and in the first chapter with the tiny little Hello World samples, it's now easier to test these.  Consider the following controller:

 

using System.Web.Mvc;
 
namespace MvcApplication.Controllers
{
    public class HelloWorld1Controller : IController
    {
        public void Execute(ControllerContext controllerContext)
        {
            controllerContext.HttpContext.Response.Write(
                "<h1>Hello World1</h1>");
        }
    }
}

 

And here's my unit test:

 

using MvcApplication.Controllers;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
 
namespace MvcApplicationTest.Controllers
{
    [TestFixture]
    public class HelloWorld1ControllerTester
    {
        [Test]
        public void ShouldRender()
        {
            var response = new ResponseWriteStub();
            var contextStub = new HttpContextStub(response);
            var controller = new HelloWorld1Controller();
 
            controller.Execute(new ControllerContextStub(controller, contextStub));
 
            Assert.That(response.ActualWritten, Is.EqualTo("<h1>Hello World1</h1>"));
        }
    }
}

 

Pretty darned simple.  Below are my stub classes.

 

 

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
 
namespace MvcApplicationTest
{
    public class ControllerContextStub : ControllerContext
    {
        public ControllerContextStub(IController controller)
            : base(new RequestContext(new HttpContextStub(), new RouteData()), controller)
        {
        }
 
        public ControllerContextStub(IController controller, HttpContextBase contextBase)
            : base(new RequestContext(contextBase, new RouteData()), controller)
        {
        }
    }
}

 

 

using System.Web;
 
namespace MvcApplicationTest
{
    public class HttpContextStub : HttpContextBase
    {
        private readonly HttpResponseBase _response;
 
        public HttpContextStub(HttpResponseBase response)
        {
            _response = response;
        }
 
        public HttpContextStub()
        {
            
        }
 
        public override HttpResponseBase Response
        {
            get { return _response; }
        }
    }
}

 

 

using System.Web;
 
namespace MvcApplicationTest.Controllers
{
    public class ResponseWriteStub : HttpResponseBase
    {
        public string ActualWritten;
 
        public override void Write(string s)
        {
            ActualWritten = s;
        }
    }
}


Comments

Ayende Rahien said:

Jeffrey,

Huh?

This is not testing a controller. This is testing IHttpHandler. The interface is just the same, and the implications of that are likewise. No one is likely to work at this level.

What is important is showing testability for the real scenario, inheriting from Controller

# March 22, 2008 2:39 AM

jonnii said:

Why are you not using a mocking framework?

# March 22, 2008 6:21 AM

Jeffrey Palermo said:

@Ayende,

Just give me a chance.  In my book, I'm going through all kinds of scenarios, and this is one of the most basic.  Previously, I didn't even write a unit test for this because it was such a pain.

# March 22, 2008 11:30 AM

Jeffrey Palermo said:

@ jonnii,

I chose not to use a mocking library for this blog post because it would clutter the sample.

# March 22, 2008 11:31 AM

Dew Drop - March 22, 2008 | Alvin Ashcraft's Morning Dew said:

Pingback from  Dew Drop - March 22, 2008 | Alvin Ashcraft's Morning Dew

# March 22, 2008 2:41 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

This Blog

Syndication