在测试init方法模拟HttpContext.Current [英] Mock HttpContext.Current in Test Init Method

查看:165
本文介绍了在测试init方法模拟HttpContext.Current的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图单元测试添加到ASP.NET MVC应用程序,我已经建立。在我的单元测试我用下面的code:

I'm trying to add unit testing to an ASP.NET MVC application I have built. In my unit tests I use the following code:

[TestMethod]
public void IndexAction_Should_Return_View() {
    var controller = new MembershipController();
    controller.SetFakeControllerContext("TestUser");

    ...
}

通过下面的助手嘲笑控制器上下文:

With the following helpers to mock the controller context:

public static class FakeControllerContext {
    public static HttpContextBase FakeHttpContext(string username) {
        var context = new Mock<HttpContextBase>();

        context.SetupGet(ctx => ctx.Request.IsAuthenticated).Returns(!string.IsNullOrEmpty(username));

        if (!string.IsNullOrEmpty(username))
            context.SetupGet(ctx => ctx.User.Identity).Returns(FakeIdentity.CreateIdentity(username));

        return context.Object;
    }

    public static void SetFakeControllerContext(this Controller controller, string username = null) {
        var httpContext = FakeHttpContext(username);
        var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
        controller.ControllerContext = context;
    }
}

该测试类从具有下列基类继承:

This test class inherits from a base class which has the following:

[TestInitialize]
public void Init() {
    ...
}

在此方法中调用的库(我却无法控制),它试图运行下面的code:

Inside this method it calls a library (which i have no control over) which tries to run the following code:

HttpContext.Current.User.Identity.IsAuthenticated

现在你或许可以看到这个问题。我已经设置了假的HttpContext对控制器,但在此基础Init方法。单元测试/嘲讽是很新的给我,所以我要确保我得到这个权利。是什么使得它在我的控制器和被称为在我的初始化方法的库共享我嘲笑了HttpContext的正确途径。

Now you can probably see the problem. I have set the fake HttpContext against the controller but not in this base Init method. Unit testing / mocking is very new to me so I want to make sure I get this right. What is the correct way for me to Mock out the HttpContext so that it is shared across my controller and any libraries which are called in my Init method.

推荐答案

HttpContext.Current 返回<一个实例href=\"http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx\"><$c$c>System.Web.HttpContext,不延伸<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.httpcontextbase.aspx\"><$c$c>System.Web.HttpContextBase. HttpContextBase 后来加入到地址的HttpContext 暂时难以嘲笑。这两个类基本上是无关的(<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.httpcontextwrapper.aspx\"><$c$c>HttpContextWrapper作为他们之间的适配器)。

HttpContext.Current returns an instance of System.Web.HttpContext, which does not extend System.Web.HttpContextBase. HttpContextBase was added later to address HttpContext being difficult to mock. The two classes are basically unrelated (HttpContextWrapper is used as an adapter between them).

幸运的是,的HttpContext 本身就是刚好够你做替换fakeable的的IPrincipal (用户)和的IIdentity

Fortunately, HttpContext itself is fakeable just enough for you do replace the IPrincipal (User) and IIdentity.

以下code运行正常,即使是在一个控制台应用程序:

The following code runs as expected, even in a console application:

HttpContext.Current = new HttpContext(
    new HttpRequest("", "http://tempuri.org", ""),
    new HttpResponse(new StringWriter())
    );

// User is logged in
HttpContext.Current.User = new GenericPrincipal(
    new GenericIdentity("username"),
    new string[0]
    );

// User is logged out
HttpContext.Current.User = new GenericPrincipal(
    new GenericIdentity(String.Empty),
    new string[0]
    );

这篇关于在测试init方法模拟HttpContext.Current的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆