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();

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))
    .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.

April 25, 2012

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!

May 24, 2012

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