【问题标题】:ASP.NET MVC - Unit testing, mocking HttpContext without using any mock frameworkASP.NET MVC - 单元测试,在不使用任何模拟框架的情况下模拟 HttpContext
【发布时间】:2011-04-09 08:53:10
【问题描述】:

由于我在使用 Moq 框架 (ASP.NET MVC - Unit testing RenderPartialViewToString() with Moq framework?) 对 RenderPartialViewToString() 进行单元测试时遇到问题,我正在考虑直接获取我的控制器,而不使用 Moq 进行这些特定测试,但是,我如何模拟(或为我的测试设置 HttpContext 而不使用任何 Moq 框架?

我需要能够做类似的事情,当然没有起订量:

    var mockHttpContext = new Mock<ControllerContext>();

    mockHttpContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("n1\\test");
    mockHttpContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

非常感谢。

【问题讨论】:

    标签: asp.net asp.net-mvc unit-testing asp.net-mvc-2 httpcontext


    【解决方案1】:

    如果您的控制器需要来自 HttpContext 的身份验证信息,我会:

    1. 创建一个新类来包装您关心的调用。看起来你想要 Name 和 IsAuthenticated。新类可以是 AuthenticationService 什么的。
    2. 在 AuthenticationService 的方法/属性中,调用 real HttpContext,如 HttpContext.Current.user.Identity.Name。
    3. 在新的接口上创建一个接口 AuthenticationService 与 您关心的公共方法/属性。
    4. 注入 IAuthenticationService 进入你的被测控制器 构造函数。看起来您可能已经在使用控制器中的其他依赖项进行此操作。
    5. 现在您可以模拟 IAuthenticationService 和它的 无需返回值 调用真正的 HttpContext。

    以下是我在http://www.volaresystems.com/Blog/post/2010/08/19/Dont-mock-HttpContext.aspx 所做的博客文章中的更多详细信息。我使用的是 RhinoMocks 而不是 Moq,但这个概念与远离 HttpContext 的概念相同。

    【讨论】:

    • 感谢 Joe,我的第一部分工作正常(“模拟”HttpContext),但仍然遇到无法测试 RenderPartialViewToString() 方法的问题 :)
    • 我现在看到了您尝试测试的原始博客文章代码。只需点击几下即可。该 BaseController 需要相同的概念 - 具有 IControllerContext(以及该类所依赖的任何其他内容)的构造函数,由调用测试传入。然后使用 _controllerContext 的私有字段,该字段在该参数的构造函数中设置。在 RenderPartialViewToString(string viewName, object model) 方法中调用这个私有字段,测试应该使用你的模拟值而不是实时的 ControllerContext 值。
    【解决方案2】:

    您可以按如下方式模拟它并声明一个接受输出的 stringBuilder 对象。

            var response = new Mock<HttpResponseBase>();
            response.Setup(x => x.Write(It.IsAny<string>())).Callback<string>(y => _stringBuilder.Append(y));
            var url = new Uri("http://localhost/Home/");
            var request = new Mock<HttpRequestBase>();
            request.Setup(x => x.Url).Returns(url);
            request.Setup(x => x.ApplicationPath).Returns("");
            var httpContext = new Mock<HttpContextBase>();
            httpContext.Setup(x => x.Request).Returns(request.Object);
            httpContext.Setup(x => x.Response).Returns(response.Object);
    
            _controllerContext = new Mock<ControllerContext>();
            _controllerContext.Setup(x => x.HttpContext).Returns(httpContext.Object);
            _homeController = autoMock.Create<HomeController>();
            _homeController.ControllerContext = _controllerContext.Object;
    

    您按如下方式执行您的操作:

    var action=_homeController.Action(<parameters>);
    action.ExecuteResult();
    

    现在您的 stringbuilder 对象,即 _stringBuilder 将输出任何类型的结果,您可以对其进行测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      相关资源
      最近更新 更多