ASP.NET MVC:如何模拟Url.Content(“~”)?

4

有没有人知道如何模拟 Url.Content("~")

(顺便说一句:我正在使用 Moq)


Url是什么?它是一种类型吗?还是一个属性? - Mark Seemann
它是一个 UrlHelper 类型的属性(获取)。 - Omu
4个回答

10

我想你是在指控制器中的Url属性,它是UrlHelper类型的。我们唯一能够模拟这个的方法是提取一个IUrlHelper接口,并创建一个UrlHelperWrapper类,该类既实现了接口又包装了本机UrlHelper类型。然后,我们像这样在BaseController上定义一个新的属性:

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

这样可以创建IUrlHelper的模拟对象并注入到代码中,但默认情况下会使用UrlHelperWrapper类的实例。抱歉这么说话啰嗦,但正如你发现的那样,否则会有问题。不过它可以直接插入,而无需更改控制器中任何Url.Action及其类似调用。

以下是该接口:

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

我不会费力给你解释 UrlHelperWrapper 的定义 - 它实际上只是一个愚蠢的包装器,它实现了这个,并将所有调用都传递给 UrlHelper


实际上,我已经完成了这个,没有用到这些东西,我会发布我的答案。 - Omu
有人有如何设置David答案中的UrlHelperWrapperBaseController的示例吗? 我尝试实现这个但无法弄清楚标准的UrlHelper将如何传递到BaseController的Url属性中。 UrlHelper类型无法转换为'IUrlHelper'。 - Chris Morgan

1

0

我知道这个内容有点老,但这是我现在的做法:

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"));
            }
        } 
    }
}

0

这是我的一个方法,用于模拟url.content(并将IsAjaxRequest()设置为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);
}

严格来说,这并不是在嘲笑UrlHelper,因此您不能对调用Url.Content的期望进行设置... - David M
明白了,我只是没有关注预期。 - Omu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接