4

anybody knows how to mock Url.Content("~") ?

(BTW: I'm using Moq)

2
  • What is Url? Is it a type? A Property? Commented Jan 19, 2010 at 8:29
  • it's UrlHelper type property (get) Commented Jan 19, 2010 at 8:33

4 Answers 4

10

You are referring to the Url property in the controllers, I presume, which is of type UrlHelper. The only way we have been able to mock this is to extract an IUrlHelper interface, and create a UrlHelperWrapper class that both implements it and wraps the native UrlHelper type. We then define a new property on our BaseController like so:

public new IUrlHelper Url
{
    get { return _urlHelper; }
    set { _urlHelper = value; }
}

This allows us to create mocks of IUrlHelper and inject them, but in the default case to use an instance of our UrlHelperWrapper class. Sorry it's long winded, but as you have discovered, it's a problem otherwise. It does, however, drop in without the need to change any of your Url.Action and similar calls in your controllers.

Here's the interface:

public interface IUrlHelper
{
    string Action(string actionName);
    string Action(string actionName, object routeValues);
    string Action(string actionName, string controllerName);
    string Action(string actionName, RouteValueDictionary routeValues);
    string Action(string actionName, string controllerName, object routeValues);
    string Action(string actionName, string controllerName, RouteValueDictionary routeValues);
    string Action(string actionName, string controllerName, object routeValues, string protocol);
    string Action(string actionName, string controllerName, RouteValueDictionary routeValues, string protocol, string hostName);
    string Content(string contentPath);
    string Encode(string url);
    string RouteUrl(object routeValues);
    string RouteUrl(string routeName);
    string RouteUrl(RouteValueDictionary routeValues);
    string RouteUrl(string routeName, object routeValues);
    string RouteUrl(string routeName, RouteValueDictionary routeValues);
    string RouteUrl(string routeName, object routeValues, string protocol);
    string RouteUrl(string routeName, RouteValueDictionary routeValues, string protocol, string hostName);
}

I won't bother giving you the definition of UrlHelperWrapper - it really is just a dumb wrapper that implements this, and passes all calls through to UrlHelper.

Sign up to request clarification or add additional context in comments.

2 Comments

actually I already did it without all this stuff, I will post my own answer
Anyone have an example of how to setup the UrlHelperWrapper and BaseController from David's answer? I tried to implement this but could not figure out how the standard UrlHelper would be passed in to the BaseController's Url property. The UrlHelper type is not convertable to the 'IUrlHelper'.
1
controller.Url = Substitute.ForPartsOf<UrlHelper>();
controller.Url.Content("~").Returns("path");

Fell free with ForPartsOf (Partial subs and test spies) in NUnit

Comments

0

I know this content is old, but this is how I do it now:

IContentResolver.cs

using System.Web;

namespace Web.Controllers
{
    public interface IContentResolver
    {
        string Resolve(string imageLocation, HttpRequestBase httpRequestBase);
    }
}

ContentResolver.cs

using System.Web;
using System.Web.Mvc;

namespace Web.Controllers
{
    public class ContentResolver : IContentResolver
    {
        public string Resolve(string imageLocation, HttpRequestBase httpRequestBase)
        {
            return new UrlHelper(httpRequestBase.RequestContext).Content(imageLocation);
        }
    }
}

ContentResolverTests.cs

using System.Web;
using System.Web.Routing;
using Web.Controllers;
using Moq;
using NUnit.Framework;

namespace Web.Tests.Controllers
{
    public class ContentResolverTests
    {
        [TestFixture]
        public class when_resolving_the_content_images
        {
            [Test]
            public void then_should_resolve_to_proper_location()
            {
                // Arrange
                var resolver = new ContentResolver();

                // Act
                var httpContextBase = new Mock<HttpContextBase>();
                var httpRequestBase = new Mock<HttpRequestBase>();

                httpContextBase.Setup(@base => @base.Request).Returns(httpRequestBase.Object);

                httpRequestBase.Setup(@base => @base.ApplicationPath).Returns("/Test");


                var requestContext = new Mock<RequestContext>();
                requestContext.SetupGet(context => context.HttpContext).Returns(httpContextBase.Object);

                httpRequestBase.SetupGet(@base => @base.RequestContext).Returns(requestContext.Object);

                var url = resolver.Resolve("~/Content/loading.gif", httpRequestBase.Object);

                // Assert
                Assert.That(url, Is.EqualTo("/Test/Content/loading.gif"));
            }
        } 
    }
}

Comments

0

this is a method of mine that mocks the url.content (and also sets the IsAjaxRequest() to true)

public static void SetContextWithAjaxRequestAndUrlContent(this BaseController controller)
{
    var routes = new RouteCollection();
    RouteConfigurator.RegisterRoutesTo(routes);


    var httpContextBase = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    var respone = new Mock<HttpResponseBase>();


    httpContextBase.Setup(x => x.Request).Returns(request.Object);
    httpContextBase.Setup(x => x.Response).Returns(respone.Object);

    request.Setup(x => x.Form).Returns(new NameValueCollection());
    request.SetupGet(x => x.Headers).Returns(new System.Net.WebHeaderCollection {{"X-Requested-With", "XMLHttpRequest"}});
    request.Setup(o => o.ApplicationPath).Returns("/Account");
    request.Setup(o => o["X-Requested-With"]).Returns("XMLHttpRequest");

    respone.Setup(o => o.ApplyAppPathModifier("/Account")).Returns("/Account");

    controller.ControllerContext = new ControllerContext(httpContextBase.Object, new RouteData(), controller);

    controller.Url = new UrlHelper(new RequestContext(controller.HttpContext, new RouteData()), routes);
}

2 Comments

That's not strictly speaking mocking the UrlHelper, so you can't set an expectation on a call to Url.Content ...
got it, I just didn't care about the expectation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.