Dmy*_*tro 4 c# unit-testing html-helper moq asp.net-mvc-3
嗯...问题更复杂,然后问题标题说.首先,我有一个HtmlHelper的扩展方法,它根据当前的路由参数生成带参数的html链接.也就是说,如果我在页面上.../page?param1=val1¶m2=val2,当我调用我的方法ActionQuryLink来生成链接时,@Html.ActionQuryLink("link text", "action", new { param3 = "value3" })我会得到一个链接<a href=".../page?param1=val1¶m2=val2¶m3=value3">link text</a>.好吧,扩展类本身是:
public static class ActionLinkHelper
{
public static MvcHtmlString ActionQueryLink(this HtmlHelper htmlHelper, string linkText, string action)
{
return (ActionQueryLink(htmlHelper, linkText, action, null, null));
}
public static MvcHtmlString ActionQueryLink(this HtmlHelper htmlHelper, string linkText, string action, object routeValues)
{
/*line 16*/return (ActionQueryLink(htmlHelper, linkText, action, routeValues, null));
}
public static MvcHtmlString ActionQueryLink(this HtmlHelper htmlHelper, string linkText, string action, object routeValues, IDictionary<string, object> htmlAttributes)
{
var queryString = htmlHelper.ViewContext.HttpContext.Request.QueryString;
var newRoute = routeValues == null
? htmlHelper.ViewContext.RouteData.Values
: new RouteValueDictionary(routeValues);
foreach(string key in queryString.Keys)
{
if(!newRoute.ContainsKey(key))
newRoute.Add(key, queryString[key]);
}
/*line 32*/string generatedLink = HtmlHelper.GenerateLink(
htmlHelper.ViewContext.RequestContext,
htmlHelper.RouteCollection,
linkText,
null,
action,
null,
newRoute,
htmlAttributes);
return new MvcHtmlString(generatedLink);
}
}
Run Code Online (Sandbox Code Playgroud)
主要问题是测试这种扩展方法
我的单元测试看起来像:
[TestClass]
public class ActionLinkHeplerTests
{
#region ActionQueryLink
[TestMethod]
public void ActionLinkHeplerShouldGenerateCorrectActionLink()
{
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.Request.QueryString).Returns(new NameValueCollection { { "param1", "value1" } });
mockHttpContext.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath).Returns("~/");
mockHttpContext.Setup(c => c.Request.ApplicationPath).Returns("~/");
mockHttpContext.Setup(c => c.Request.CurrentExecutionFilePath).Returns("~/");
var mockProductRepository = new Mock<IProductRepository>();
mockProductRepository.Setup(p => p.GetCategory(It.IsAny<string>())).Returns(new Category());
var mockSettings = new Mock<ISettings>();
var categoryController = new CategoryController(mockProductRepository.Object, mockSettings.Object);
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(e => e.ViewData).Returns(new ViewDataDictionary { { "action", "action" } });
var viewContext = new ViewContext
{
HttpContext = categoryController.HttpContext,
RequestContext = new RequestContext
{
HttpContext = mockHttpContext.Object,
RouteData = new RouteData()
}
};
var mockRouteHandler = new Mock<IRouteHandler>();
var helper = new HtmlHelper(viewContext, mockViewDataContainer.Object, new RouteCollection { { "action", new Route("controller/action", mockRouteHandler.Object) } });
var expected = new MvcHtmlString("");
/*line 51*/var actual = helper.ActionQueryLink("link text", "action", new {view = "list"});
Assert.AreEqual(expected, actual);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
我得到了这样的例外:
Test method TestSite.UnitTests.Helpers.ActionLinkHeplerTests.ActionLinkHeplerShouldGenerateCorrectActionLink threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.
Run Code Online (Sandbox Code Playgroud)
和堆栈跟踪:
at System.Web.UI.Util.GetUrlWithApplicationPath(HttpContextBase context, String url)
at System.Web.Routing.RouteCollection.NormalizeVirtualPath(RequestContext requestContext, String virtualPath)
at System.Web.Routing.RouteCollection.GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
at System.Web.Mvc.RouteCollectionExtensions.GetVirtualPathForArea(RouteCollection routes, RequestContext requestContext, String name, RouteValueDictionary values, ref Boolean usingAreas)
at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues)
at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, String protocol, String hostName, String fragment, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues)
at System.Web.Mvc.HtmlHelper.GenerateLinkInternal(RequestContext requestContext, RouteCollection routeCollection, String linkText, String routeName, String actionName, String controllerName, String protocol, String hostName, String fragment, RouteValueDictionary routeValues, IDictionary`2 htmlAttributes, Boolean includeImplicitMvcValues)
at System.Web.Mvc.HtmlHelper.GenerateLink(RequestContext requestContext, RouteCollection routeCollection, String linkText, String routeName, String actionName, String controllerName, String protocol, String hostName, String fragment, RouteValueDictionary routeValues, IDictionary`2 htmlAttributes)
at System.Web.Mvc.HtmlHelper.GenerateLink(RequestContext requestContext, RouteCollection routeCollection, String linkText, String routeName, String actionName, String controllerName, RouteValueDictionary routeValues, IDictionary`2 htmlAttributes)
at Core.Helpers.ActionLinkHelper.ActionQueryLink(HtmlHelper htmlHelper, String linkText, String action, Object routeValues, IDictionary`2 htmlAttributes) in ActionLinkHelper.cs: line 32
at Core.Helpers.ActionLinkHelper.ActionQueryLink(HtmlHelper htmlHelper, String linkText, String action, Object routeValues) in ActionLinkHelper.cs: line 16
at TestSite.UnitTests.Helpers.ActionLinkHeplerTests.ActionLinkHeplerShouldGenerateCorrectActionLink() in ActionLinkHeplerTests.cs: line 51
Run Code Online (Sandbox Code Playgroud)
好吧,我真的很抱歉这批代码.
但我正在研究这个问题大约3天.正如您所看到的,甚至在某些MVC库中也没有出现错误System.Web.UI.Util.即使我可以找到System.Web.UI.Util源代码并将其作为另一个项目添加到我的解决方案中,我也无法强制MVC框架使用此项目而不是System.Web.UI.Util全局汇编现金.老实说,在我的解决方案中将MVC从GAC替换为MVC的源项目甚至非常困难,因为它非常复杂,存在很多依赖关系,当我尝试这样做时,我遇到了很多错误,其中大多数错误是外部库已经使用全球汇编现金的MVC汇编.最重要的是,我的帮助方法在我的项目中工作正常,它只在测试时调用异常.所以我的建议是帮助者的测试条件不完整或可能是错误的.总之,我的问题是我怎么能嘲笑我的HTML辅助扩展方法正确的条件下,使用起订量,或者,也许,有一些其他的问题?
Ale*_*kov 10
原来,要测试依赖路由信息的助手,需要模拟以下方法RequestContext.HttpContext:
RequestContext.HttpContext.Request.ApplicationPath- 应该返回类似根路径的东西(即@"/")RequestContext.HttpContext.Response.ApplyAppPathModifier - 可以简单地返回其输入参数: 样品:
request.Setup(r => r.ApplicationPath).Returns(@"/");
response.Setup(r => r.ApplyAppPathModifier(It.IsAny<string>()))
.Returns((string s) => s);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1989 次 |
| 最近记录: |