random .NET and web development musings

In order to use the UrlHelper class in your tests, you need to construct it with a ControllerContext, which consists of an HttpRequest and an HttpResponse. Unfortunately these are quite difficult to construct, as you’ll know if you’ve ever tried. Luckily, the UrlHelper doesn’t use much of these two classes, only a few properties, making them fairly easy to mock.

The first thing you need to do is get your routes, usually declared in your Global.asax MvcApplication

var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);

Then you need to mock an HttpRequest

var request = MockRepository.GenerateStub<HttpRequestBase>();
request.Stub(x => x.ApplicationPath).Return("/");
request.Stub(x => x.Url).Return(new Uri("http://localhost/a", UriKind.Absolute));
request.Stub(x => x.ServerVariables).Return(new System.Collections.Specialized.NameValueCollection());

Then you need to mock the HttpResponse

var response = MockRepository.GenerateStub<HttpResponseBase>();
response.Stub(x => x.ApplyAppPathModifier(Arg<string>.Is.Anything))
    .Return(null)
    .WhenCalled(x => x.ReturnValue = x.Arguments[0]);

Then you can simply stick these two mocks onto a mock context, and use that to create your UrlHelper instance and set them on the controller you are testing:

var context = MockRepository.GenerateStub<HttpContextBase>();
context.Stub(x => x.Request).Return(request);
context.Stub(x => x.Response).Return(response);

var subjectUnderTest = new MyController(); // this is the controller you are testing

subjectUnderTest.ControllerContext = new ControllerContext(context, new RouteData(), subjectUnderTest);
subjectUnderTest.Url = new UrlHelper(new RequestContext(context, new RouteData()), routes);

Job done.

Now go and use OpenRasta and not have any of these problems.

2 COMMENTS
sydneyos
April 25, 2012
ad

Awesome. I don’t need to use UrlHelper in my tests, but my controller actions are using UrlHelper all over the place, and after upgrading to MVC3, tests of these actions were all failing. A slight variation on this solved that problem. Thanks!

Pawel
May 24, 2012
ad

Thanks a lot! I had request and response mocked, but was struggling with the UrlHelper part. Even searching on stackoverflow did not help this time, your blog post solved the issue.

Post a comment