如何為模型設置 IPrincipal?
我想模擬 IPrincipal 所以我這樣做了
public Mock<IPrincipal> Principal { get; set; }在我的 nunit 設置中
Principal = new Mock<IPrincipal>();所以這應該是我在 nunit 單元測試中所需要的,但是在我的實際控制器文件中呢?
比如我該如何設置?
例如我有一個membership.Provider
所以我所做的是在我的控制器建構子中
Provider = Membership.Provider;因此,在我的控制器中,我只使用了 Provider。(無論我需要什麼)。
我不確定如何以相同的方式設置 Principal 。
你在談論 ASP.NET MVC 嗎?大概吧。
您必須創建控制器實例並設置其 RequestContext。你模擬 RequestContext 的 HttpContext,在這個 HttpContext 中,你模擬它的 User 屬性,並將它設置為你模擬的 IPrincipal:
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);希望這可以幫助。
編輯:
僅供參考,Controller 類的 User 屬性來自 HttpContext 對象,正如您在此處看到的(這是 User 屬性的 getter 方法,從 Reflector 獲得——您也可以下載 ASP.NET MVC 原始碼):
public IPrincipal User { get { if (this.HttpContext != null) { return this.HttpContext.User; } return null; } }如果您現在檢查 HttpContext 屬性,您將看到:
public HttpContextBase HttpContext { get { if (base.ControllerContext != null) { return base.ControllerContext.HttpContext; } return null; } }所以,到目前為止,一切都是“只讀的”。我們需要一種“注入”模擬“使用者”的方法。因此,我們檢查我們是否可以通過屬性在控制器上實際注入 ControllerContext 對象。我們驗證它是如何獲取其“HttpContext”對象的,以了解如何正確地模擬它:
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 。所以這可以解釋我上面做了什麼:
- 用你想要的數據模擬一個 IPrincipal,
- 模擬一個 HttpContext,並用 IPrincipal 提供它,
- 模擬一個 RequestContext,並用 HttpContext 餵牠,
- 創建控制器的實例並將其 ControllerContext 屬性設置為模擬的 RequestContext 對象。
在所有這些魔法之後,控制器將不知道您正在呼叫它而沒有通過 Web 伺服器建立實際連接。
因此,您可以像往常一樣繼續在控制器中使用“使用者”屬性,無需進行任何更改。