How to unit test a custom Controller Factory in ASP .NET MVC?

Using Inversion of Control (IoC) and Dependency Injection (DI) with MVC is an extremely powerful architecture choice. In the MVC world, this usually means implementing a customized controller factory that hooks in to your DI container and supplies dependencies to your controller classes. Since this controller functionality is no longer standard MVC, it’s a good idea to test its operation. However this is one of the challenges as some of the methods you can override are not public but protected.

Here is my simplified custom controller factory:

    public class CustomControllerFactory : DefaultControllerFactory
    {
        private readonly IWindsorContainer _windsorContainer;

        public CustomControllerFactory(IWindsorContainer windsorContainer)
        {
            _windsorContainer = windsorContainer;
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
            {
                throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
            }

            if (_windsorContainer.Kernel.HasComponent(controllerType))
            {
                return (IController)_windsorContainer.Resolve(controllerType);
            }

            return base.GetControllerInstance(requestContext, controllerType);
        }
    }

You will notice, I have overridden the GetControllerInstance method in order to hook into my DI container – in this case Castle Windsor. And this is usually something you would want to test, especially if you have additional functionality (such as overrides) built into this method.

So how to test? The short answer: Reflection to the rescue. Invoke the protected method like so:

var method2 = (typeof(WindsorControllerFactory)).GetMethod("GetControllerInstance", BindingFlags.Instance | BindingFlags.NonPublic);

Assert.IsNotNull(result2);

var result2 = method2.Invoke(controllerFactory, new object[] { mockHttp.Request.RequestContext, typeof(HomeController) });

Assert.AreEqual("HomeController", result2.GetType().Name);

Simple and effective, and now you’re able to test your assertions against the output of this method.

Advertisements
Explore posts in the same categories: ASP .NET MVC, Development

Tags: ,

You can comment below, or link to this permanent URL from your own site.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: