[英]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.