gpt4 book ai didi

asp.net-mvc - 如何让单元测试在 ASP.NET MVC 中使用路由?

转载 作者:行者123 更新时间:2023-12-05 02:25:12 24 4
gpt4 key购买 nike

我正在针对我的 ASP.NET MVC 应用程序编写单元测试,特别是我正在测试我编写的 HtmlHelper 扩展方法。扩展方法里面有一行:

var innerHtml = htmlHelper.ActionLink(text, action, controller, routeValues, null);

当我在单元测试中运行它时,生成的 URL 的 href 为空,无论传入的是什么操作或 Controller 。

这是我的单元测试:

var page = CreateProductDataPage(); //returns ProductDataPage object
var htmlHelper = Http.CreateHtmlHelperWithMocks<ProductDataPage>(new ViewDataDictionary<ProductDataPage>(page), false);
var result = htmlHelper.ProductListingBreadcrumb(true, null, null);

这是 CreateHtmlHelperWithMocks 方法:

public static HtmlHelper<T> CreateHtmlHelperWithMocks<T>(ViewDataDictionary<T> viewData, bool isLoggedIn) where T : class
{
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData);

return new HtmlHelper<T>(GetViewContextMock(viewData, isLoggedIn).Object, mockViewDataContainer.Object);
}

最后,这里是 GetViewContextMock 方法:

public static Mock<ViewContext> GetViewContextMock(ViewDataDictionary viewData, bool isLoggedIn)
{
var mock = new Mock<ViewContext>();

mock.SetupGet(v => v.HttpContext).Returns(GetHttpContextMock(isLoggedIn).Object);
mock.SetupGet(v => v.Controller).Returns(new Mock<ControllerBase>().Object);
mock.SetupGet(v => v.View).Returns(new Mock<IView>().Object);
mock.SetupGet(v => v.ViewData).Returns(viewData);
mock.SetupGet(v => v.TempData).Returns(new TempDataDictionary());
mock.SetupGet(v => v.RouteData).Returns(new RouteData());

return mock;
}

最佳答案

更新:想通了。多么痛苦啊。万一其他人试图这样做......

第一步是在创建模拟 HtmlHelper 时从 global.asax 添加路由集合。

    public static HtmlHelper<T> CreateHtmlHelperWithMocks<T>(ViewDataDictionary<T> viewData, bool isLoggedIn) where T : class
{
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData);

//These next two lines are key:
var routeCollection = new RouteCollection();
MvcApplication.RegisterRoutes(routeCollection);

return new HtmlHelper<T>(GetViewContextMock(viewData, isLoggedIn).Object, mockViewDataContainer.Object, routeCollection);
}

然后我必须确保 HttpContext mock 为请求的 ApplicationPath 属性和响应的 ApplyAppPathModifier 方法返回结果。

    public static Mock<HttpContextBase> GetHttpContextMock(bool isLoggedIn)
{
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
var principal = AuthenticationAndAuthorization.GetPrincipleMock(isLoggedIn);

//These next two lines are required for the routing to generate valid URLs, apparently:
request.SetupGet(r => r.ApplicationPath).Returns("/");
response.Setup(r => r.ApplyAppPathModifier(It.IsAny<string>())).Returns((string r) => r);

context.SetupGet(c => c.Request).Returns(request.Object);
context.SetupGet(c => c.Response).Returns(response.Object);
context.SetupGet(c => c.Session).Returns(session.Object);
context.SetupGet(c => c.Server).Returns(server.Object);
context.SetupGet(c => c.User).Returns(principal.Object);

return context;
}

关于asp.net-mvc - 如何让单元测试在 ASP.NET MVC 中使用路由?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1856795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com