asp.net mvc How to test controllers correctly

Posted by Simon G on Stack Overflow See other posts from Stack Overflow or by Simon G
Published on 2010-06-18T10:25:02Z Indexed on 2010/06/18 10:33 UTC
Read the original article Hit count: 281

Filed under:
|
|

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

© Stack Overflow or respective owner

Related posts about asp.net-mvc

Related posts about unit-testing