Urls for menus in my ASP.NET MVC apps are generated from controller/actions. So, they call
controller.Url.Action(action, controller)
Now, h
Here's how you could mock UrlHelper using MvcContrib's TestControllerBuilder:
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
HomeController controller = CreateController<HomeController>();
controller.HttpContext.Response
.Stub(x => x.ApplyAppPathModifier("/Home/About"))
.Return("/Home/About");
controller.Url = new UrlHelper(
new RequestContext(
controller.HttpContext, new RouteData()
),
routes
);
var url = controller.Url.Action("About", "Home");
Assert.IsFalse(string.IsNullOrEmpty(url));
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);
A cleaner way to do this is just use Moq(or any other framework you like) to Mock UrlHelper itself
var controller = new OrdersController();
var UrlHelperMock = new Mock<UrlHelper>();
controller.Url = UrlHelperMock.Object;
UrlHelperMock.Setup(x => x.Action("Action", "Controller", new {parem = "test"})).Returns("testUrl");
var url = controller.Url.Action("Action", "Controller", new {parem = "test"});
assert.areEqual("/Controller/Action/?parem=test",url);
clean and simple.
Fake it easy works nicely:
var fakeUrlHelper = A.Fake<UrlHelper>();
controller.Url = fakeUrlHelper;
A.CallTo(() => fakeUrlHelper.Action(A<string>.Ignored, A<string>.Ignored))
.Returns("/Action/Controller");
If you're using Moq
(and not MvcContrib
's TestControllerBuilder
), you can mock out the context, similar to @DarianDimitrov's answer:
var controller = new OrdersController();
var context = new Mock<System.Web.HttpContextBase>().Object;
controller.Url = new UrlHelper(
new RequestContext(context, new RouteData()),
new RouteCollection()
);
This doesn't set the controller.HttpContext
property, but it does allow Url.Action
to execute (and return an empty string -- no mocking required).