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

6

由于在使用Moq框架进行单元测试RenderPartialViewToString()时遇到了问题(ASP.NET MVC - Unit testing RenderPartialViewToString() with Moq framework?),我考虑直接获取我的控制器,而不是使用Moq进行这些特定的测试,但是,如何在没有使用任何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);

Thank you very much.

2个回答

3
如果您的控制器需要从HttpContext获取身份验证信息,我会:
  1. 创建一个新类来包装您关心的调用。看起来您想要名称和IsAuthenticated。新类可以是AuthenticationService或其他名称。
  2. 在AuthenticationService中的方法/属性中调用“真正的”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()方法的问题 :) - Saxman
我现在看到你正在尝试测试的原始博客文章代码。 它只需要同样的概念 - 通过调用测试传递一个IControllerContext(以及类所依赖的任何其他内容)的构造函数。 然后在构造函数中使用一个私有字段_controllerContext,从该参数设置它。 在RenderPartialViewToString(string viewName,object model)方法中调用此私有字段,测试应该使用您模拟的值而不是实际的ControllerContext值。 - Joe Wilson

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将输出结果,无论它是什么类型,你可以对其进行测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接