ASP.NET MVC - 单元测试,模拟 HttpContext 而不使用任何模拟框架

发布于 2024-09-17 21:46:31 字数 645 浏览 7 评论 0原文

由于我在使用 Moq 框架进行单元测试 RenderPartialViewToString() 时遇到问题(ASP.NET MVC - 使用 Moq 框架对 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);

非常感谢。

Since I'm having problem with unit testing RenderPartialViewToString() with Moq framework (ASP.NET MVC - Unit testing RenderPartialViewToString() with Moq framework?), I'm thinking about getting my controller directly, without using Moq for these particular test, however, how do I mocks (or set) the HttpContext for my test without using any Moq framework?

I need to able to do something similar to this, without Moq of course:

    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);

Thank you very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哥,最终变帅啦 2024-09-24 21:46:31

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

  1. 创建一个新类来包装您关心的调用。看起来您想要 Name 和 IsAuthenticated。新类可以是 AuthenticationService 或其他类。
  2. 在 AuthenticationService 的方法/属性中,调用真实 HttpContext,例如 HttpContext.Current.user.Identity.Name。
  3. 在新的基础上创建一个接口
    身份验证服务与
    您关心的公共方法/属性。
  4. 注入 IAuthenticationService
    进入您的被测控制器
    构造函数。看起来您可能已经在控制器中使用其他依赖项来执行此操作。
  5. 现在你可以嘲笑
    IAuthenticationService 及其
    无需返回值
    调用真实的 HttpContext。

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

If your controller need authentication info from HttpContext, I would:

  1. Create a new class that wraps the calls you care about. Looks like you want Name and IsAuthenticated. The new class can be AuthenticationService or something.
  2. In the methods/properties in AuthenticationService, call into the real HttpContext, like HttpContext.Current.user.Identity.Name.
  3. Create an interface over the new
    AuthenticationService with the
    public methods/properties you care about.
  4. Inject the IAuthenticationService
    into your controller under test in
    the constructor. Looks like you may already be doing that with other dependencies in the controller.
  5. Now you can mock
    IAuthenticationService and it's
    return values without needing to
    call into the real HttpContext.

Here are more details from a blog post I did http://www.volaresystems.com/Blog/post/2010/08/19/Dont-mock-HttpContext.aspx. I'm using RhinoMocks instead of Moq, but the concept is the same for staying away from HttpContext.

只是一片海 2024-09-24 21:46:31

您可以按如下方式模拟它并声明一个接受输出的 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)将具有结果输出,无论它是什么类型,您都可以测试它。

You can mock it as follows and declare a stringBuilder object that accepts the output.

        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;

You execute your action as follows:

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

and now your stringbuilder object i.e _stringBuilder will have the result output whatever type it is and you can test it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文