One of the big drivers for people moving over to ASP.NET MVC is its support for Test Driven Development/Unit Testing. The ability to automate testing of models and controllers brings a measurable level of confidence to development. In ASP.NET MVC, that means we can be sure that we are getting the expected views, data and routes from our controllers.
Unless they do something that only works in a Web context, in which case we get an exception.
The problem is that the Visual Studio Test Framework isn’t a Web client. The moment your controller does something that only works in a Web context, like accessing a session variable, your test will break with a NullReferenceException.
The controller in the test project has a Session property – but if you try and set Session variables, you will simply move the NullReferenceException up one level into your test project. That’s where MvcContrib comes in. It’s an open source project available at CodePlex, and it allows you to mock up the HttpContext and populate the Session etc. with the values your methods require.
Once you’ve downloaded MvcContrib, you need to set a reference to it inside your test project. The classes you want are inside the TestHelper namespace, so add it as an Imports. Then get the TestControllerBuilder to create the controller for you – that will give you the extra framework you need to add in the HttpContext elements. The easiest thing to do is add a controller variable at the class level, and then call CreateController() inside a TestInitialise() method.
The TestControllerBuilder gives you a more fully featured version of the controller. Now, if you set a Session variable, the value will be passed through to the controller and you won’t get the NullReferenceException in either the test project or the controller.
So now you can run your tests and have them pass – even when your code has elements that require a HttpContext.
One gotcha to watch out for. You need to have a mocking framework available – so make sure that you also reference one of the mocking frameworks that works with TestHelper or you’ll get an exception when you try to run your tests. In the sample above, I referenced Rhino.Mocks, which is included with MvcContrib.
MvcContrib has quite a lot of other features beyond testing, and I might well come back to some of those in later posts.
For other related information, check out these courses from Learning Tree: