ASP.NET MVC: Mock controller.Url.Action

Viewed 14687

Urls for menus in my ASP.NET MVC apps are generated from controller/actions. So, they call

controller.Url.Action(action, controller)

Now, how do I make this work in unit tests? I use MVCContrib successfully with

var controller = new TestControllerBuilder().CreateController<OrdersController>();

but whatever I try to do with it I get controller.Url.Action(action, controller) failing with NullReferenceException because Url == null.

Update: it's not about how to intercept HttpContext. I did this in several ways, using MVCContrib, Scott Hanselman's example of faking, and also the one from http://stephenwalther.com/blog/archive/2008/07/01/asp-net-mvc-tip-12-faking-the-controller-context.aspx. This doesn't help me because I need to know WHAT values to fake... is it ApplicationPath? How do I set it up? Does it need to match the called controller/action? That is, how do Url.Action works and how do I satisfy it?

Also, I know I can do IUrlActionAbstraction and go with it... but I'm not sure I want to do this. After all, I have MVCContrib/Mock full power and why do I need another abstraction.

5 Answers

Here is another way to solve the problem with NSubstitute. Hope, it helps someone.

// _accountController is the controller that we try to test
var urlHelper = Substitute.For<UrlHelper>();
urlHelper.Action(Arg.Any<string>(), Arg.Any<object>()).Returns("/test_Controller/test_action");

var context = Substitute.For<HttpContextBase>();
_accountController.Url = urlHelper;
_accountController.ControllerContext = new ControllerContext(context, new RouteData(), _accountController);
Related