简体   繁体   English

asp.net mvc:如何模拟Url.Content(“〜”)?

[英]asp.net mvc: how to mock Url.Content(“~”)?

anybody knows how to mock Url.Content("~") ? 有谁知道如何模拟Url.Content("~")

(BTW: I'm using Moq) (顺便说一句:我正在使用Moq)

You are referring to the Url property in the controllers, I presume, which is of type UrlHelper . 你指的是控制器中的Url属性,我认为它属于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. 我们能够模拟这个的唯一方法是提取IUrlHelper接口,并创建一个UrlHelperWrapper类,它同时实现它并包装本机UrlHelper类型。 We then define a new property on our BaseController like so: 然后我们在BaseController上定义一个新属性, BaseController所示:

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. 这允许我们创建IUrlHelper并注入它们,但在默认情况下使用我们的UrlHelperWrapper类的实例。 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. 但是,它确实无需更改控制器中的任何Url.Action和类似的调用。

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 . 我不打算给你UrlHelperWrapper的定义 - 它实际上只是一个实现这个的愚蠢的包装器,并将所有调用传递给UrlHelper

controller.Url = Substitute.ForPartsOf<UrlHelper>();
controller.Url.Content("~").Returns("path");

Fell free with ForPartsOf (Partial subs and test spies) in NUnit 在NUnit中使用ForPartsOf(部分子和测试间谍)免费下载

this is a method of mine that mocks the url.content (and also sets the IsAjaxRequest() to true) 这是我的一种模拟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);
}

I know this content is old, but this is how I do it now: 我知道这个内容已经过时了,但这就是我现在这样做的方式:

IContentResolver.cs IContentResolver.cs

using System.Web;

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM