繁体   English   中英

如果在测试时在System.Web.UI.Util中出现异常,如何对我的HtmlHelper扩展方法进行单元测试?

How to unit test my HtmlHelper extension method if I get an exception at System.Web.UI.Util while testing?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

嗯...问题更复杂,然后问题标题说。 首先,我有一个HtmlHelper的扩展方法,它根据当前路由参数生成带参数的html链接。 也就是说,如果我在页面上.../page?param1=val1&param2=val2 ,当我调用我的方法ActionQuryLink生成链接时,例如@Html.ActionQuryLink("link text", "action", new { param3 = "value3" })我将获得<a href=".../page?param1=val1&param2=val2&param3=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);
        }
    }

主要问题是测试这种扩展方法

我的单元测试看起来像:

[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
    }

我得到了这样的例外:

Test method TestSite.UnitTests.Helpers.ActionLinkHeplerTests.ActionLinkHeplerShouldGenerateCorrectActionLink threw exception: 
System.NullReferenceException: Object reference not set to an instance of an object.

和堆栈跟踪:

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

好吧,我真的很抱歉这批代码。 但我正在研究这个问题大约3天。 正如您所看到的,即使在某些MVC库中也没有出现错误,但在System.Web.UI.Util 即使我可以找到System.Web.UI.Util源并将其作为一个项目添加到我的解决方案中,我也无法强制MVC框架使用此项目而不是来自全局程序集现金的System.Web.UI.Util 老实说,在我的解决方案中将MVC从GAC替换为MVC的源项目甚至非常困难,因为它非常复杂,存在很多依赖关系,当我尝试这样做时,我遇到了很多错误,其中大多数错误是外部库已经使用全球汇编现金的MVC汇编。 最重要的是,我的帮助方法在我的项目中工作正常,它只在测试时调用异常。 所以我的建议是帮助者的测试条件不完整或可能是错误的。 总结一下我的问题是如何使用Moq模拟我的html帮助扩展方法的正确条件,或者,是否还有其他一些问题?

1 个回复

原来,要测试依赖路由信息的助手,需要模拟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);
4 同时运行所有单元测试时出现异常

我在单元测试课中有一堆单元测试。 当我分别运行每个时,它们全部通过,但是当我同时运行它们时,第一个通过,其余都失败: System.ArgumentException:具有相同键的项已添加 谁能告诉我为什么? 以及我该如何纠正错误? 样品: 其余测试均为同 ...

6 使用spock进行java单元测试时出现异常

我正在尝试使用spock来测试我的基于java的Web应用程序。 早些时候我们曾经使用Junit和Mockito进行测试。 我正在尝试使用@Collaborator和@Subject自动装配我的依赖项,就像我们曾经在Mockito中使用@Mock和@InjectMocks一样。 但 ...

9 如何使用Moq对HtmlHelper进行单元测试?

有人可以告诉我如何使用Moq创建模拟HTML Helper吗? 本文提供了一个声称自称描述此内容的文章的链接,但是在该链接之后仅返回一个ASP.NET运行时错误。 [编辑]我问有关同一主题的一个更具体的问题在这里 ,但目前还没有得到任何回应。 我认为它太具体了,所以我认为我可以对一 ...

10 使用HtmlHelper进行DisplayFormat单元测试

我想测试通过调用DisplayFor产生的输出是否为...指定的格式。 代码可以编译,但在DisplayFor处会出现NullReferenceException失败。 谁能帮助我完成这项工作? (注意:这是一个较大问题的简单示例) ...

暂无
暂无

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

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