asp.net mvc How to test controllers correctly
- by Simon G
Hi,
I'm having difficulty testing controllers. Original my controller for testing looked something like this:
SomethingController CreateSomethingController()
{
var somethingData = FakeSomethingData.CreateFakeData();
var fakeRepository = FakeRepository.Create();
var controller = new SomethingController(fakeRepository);
return controller;
}
This works fine for the majority of testing until I got the Request.IsAjaxRequest() part of code. So then I had to mock up the HttpContext and HttpRequestBase. So my code then changed to look like:
public class FakeHttpContext : HttpContextBase
{
bool _isAjaxRequest;
public FakeHttpContext( bool isAjaxRequest = false )
{
_isAjaxRequest = isAjaxRequest;
}
public override HttpRequestBase Request
{
get
{
string ajaxRequestHeader = "";
if ( _isAjaxRequest )
ajaxRequestHeader = "XMLHttpRequest";
var request = new Mock<HttpRequestBase>();
request.SetupGet( x => x.Headers ).Returns( new WebHeaderCollection
{
{"X-Requested-With", ajaxRequestHeader}
} );
request.SetupGet( x => x["X-Requested-With"] ).Returns( ajaxRequestHeader );
return request.Object;
}
}
private IPrincipal _user;
public override IPrincipal User
{
get
{
if ( _user == null )
{
_user = new FakePrincipal();
}
return _user;
}
set
{
_user = value;
}
}
}
SomethingController CreateSomethingController()
{
var somethingData = FakeSomethingData.CreateFakeData();
var fakeRepository = FakeRepository.Create();
var controller = new SomethingController(fakeRepository);
ControllerContext controllerContext = new ControllerContext( new FakeHttpContext( isAjaxRequest ), new RouteData(), controller );
controller.ControllerContext = controllerContext;
return controller;
}
Now its got to that stage in my controller where I call Url.Route and Url is null. So it looks like I need to start mocking up routes for my controller.
I seem to be spending more time googling on how to fake/mock objects and then debugging to make sure my fakes are correct than actual writing the test code. Is there an easier way in to test a controller? I've looked at the TestControllerBuilder from MvcContrib which helps with some of the issues but doesn't seem to do everything. Is there anything else available that will do the job and will let me concentrate on writing the tests rather than writing mocks?
Thanks