首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为模型设置IPrincipal?

如何为模型设置IPrincipal?
EN

Stack Overflow用户
提问于 2009-08-21 21:46:13
回答 1查看 4.9K关注 0票数 10

我想模拟IPrincipal,所以我这样做了

代码语言:javascript
复制
public Mock<IPrincipal> Principal { get; set; }

在我的nunit设置中

代码语言:javascript
复制
 Principal = new Mock<IPrincipal>();

所以这应该就是我在nunit单元测试中所需要的了,但是在我的实际控制器文件中呢?

比如我该怎么设置它?

例如,我有一个membership.Provider

所以我所做的是在我的控制器构造函数中

代码语言:javascript
复制
Provider = Membership.Provider;

因此,在我的控制器中,我只使用了Provider。(我需要什么)。

我不确定如何以同样的方式设置主要的东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-08-21 22:26:23

你是在说ASP.NET MVC吗?可能是吧。

您必须创建控制器的一个实例并设置其RequestContext。模拟RequestContext的HttpContext,在此HttpContext中模拟其用户属性,并将其设置为模拟的IPrincipal:

代码语言:javascript
复制
var principal = new Moq.Mock<IPrincipal>();
// ... mock IPrincipal as you wish

var httpContext = new Moq.Mock<HttpContextBase>();
httpContext.Setup(x => x.User).Returns(principal.Object);
// ... mock other httpContext's properties, methods, as needed

var reqContext = new RequestContext(httpContext.Object, new RouteData());

// now create the controller:
var controller = new MyController();
controller.ControllerContext =
    new ControllerContext(reqContext, controller);

希望这能有所帮助。

编辑:

仅供参考,控制器类上的User属性来自HttpContext对象,您可以在此处看到(这是User属性的getter方法,从Reflector获得--您也可以下载ASP.NET MVC源代码):

代码语言:javascript
复制
public IPrincipal User
{
    get
    {
        if (this.HttpContext != null)
        {
            return this.HttpContext.User;
        }
        return null;
    }
}

如果现在检查HttpContext属性,您将看到:

代码语言:javascript
复制
public HttpContextBase HttpContext
{
    get
    {
        if (base.ControllerContext != null)
        {
            return base.ControllerContext.HttpContext;
        }
        return null;
    }
}

因此,到目前为止,所有内容都是“只读”的。我们需要一种方法来“注入”一个被嘲笑的“用户”。因此,我们检查是否可以通过属性在控制器上实际注入ControllerContext对象。我们验证它是如何获得其"HttpContext“对象的,以了解如何正确地模拟它:

代码语言:javascript
复制
public virtual HttpContextBase HttpContext
{
    get
    {
        if (this._httpContext == null)
        {
            this._httpContext = (this._requestContext != null) ? this._requestContext.HttpContext : new EmptyHttpContext();
        }
        return this._httpContext;
    }
    set
    {
        this._httpContext = value;
    }
}

因此,在这里我们可以看到,ControllerContext对象从一个RequestContext对象获取它的HttpContext。因此,这可能解释了我上面所做的:

  1. 使用所需数据模拟IPrincipal,
  2. 模拟HttpContext,并为其提供IPrincipal,
  3. 模拟RequestContext,并为其提供HttpContext,
  4. 创建控制器的实例并将其ControllerContext属性设置为模拟的RequestContext对象。

在所有这些魔术之后,控制器将不会知道您在没有通过Web服务器建立实际连接的情况下调用它。

因此,您可以继续像往常一样使用控制器中的"User“属性,不需要做任何更改。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1314370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档