我有一個控制器操作,如果用戶已經登錄(User.Identity.IsAuthenticated
),它會自動重定向到新頁面。爲此場景編寫單元測試以確保重定向發生的最佳方式是什麼?如何對使用Controller.User變量的控制器操作進行單元測試?
8
A
回答
14
我一直在使用下面的Mock和Moq來允許在我的單元測試中設置各種條件。首先,HttpContextBase模擬:
public static Mock<HttpContextBase> GetHttpContextMock(bool isLoggedIn)
{
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
var principal = AuthenticationAndAuthorization.GetPrincipleMock(isLoggedIn);
context.SetupGet(c => c.Request).Returns(request.Object);
context.SetupGet(c => c.Response).Returns(response.Object);
context.SetupGet(c => c.Session).Returns(session.Object);
context.SetupGet(c => c.Server).Returns(server.Object);
context.SetupGet(c => c.User).Returns(principal.Object);
return context;
}
每個屬性可能提供一個有用的模擬在這裏成立。這樣一來,如果我需要添加類似引薦,我可以只使用:
Mock.Get(controller.Request).Setup(s => s.UrlReferrer).Returns(new Uri("http://blah.com/");
的「GetPrincipleMock」的方法就是建立用戶。它看起來像這樣:
public static Mock<IPrincipal> GetPrincipleMock(bool isLoggedIn)
{
var mock = new Mock<IPrincipal>();
mock.SetupGet(i => i.Identity).Returns(GetIdentityMock(isLoggedIn).Object);
mock.Setup(i => i.IsInRole(It.IsAny<string>())).Returns(false);
return mock;
}
public static Mock<IIdentity> GetIdentityMock(bool isLoggedIn)
{
var mock = new Mock<IIdentity>();
mock.SetupGet(i => i.AuthenticationType).Returns(isLoggedIn ? "Mock Identity" : null);
mock.SetupGet(i => i.IsAuthenticated).Returns(isLoggedIn);
mock.SetupGet(i => i.Name).Returns(isLoggedIn ? "testuser" : null);
return mock;
}
現在,在測試我的控制器的設置是這樣的:
var controller = new ProductController();
var httpContext = GetHttpContextMock(true); //logged in, set to false to not be logged in
ControllerContext controllerContext = new ControllerContext(httpContext.Object, new RouteData(), controller);
controller.ControllerContext = controllerContext;
這是冗長設置的一點點,但一旦你有一切就緒,測試各種的條件變得更容易。
7
這不是最簡單的事情,但它可以做到。 User屬性只是委託給Controller.HttpContext.User。兩者都是非虛擬的只讀屬性,所以你不能對它們做任何事情。但是,Controller.HttpContext委託給ControllerBase.ControllerContext,它是一個可寫屬性。
因此,在執行被測系統(SUT)之前,您可以將Test Double HttpContextBase分配給Controller.ControllerContext。使用Moq,它看起來像這樣:
var user = new GenericPrincipal(new GenericIdentity(string.Empty), null);
var httpCtxStub = new Mock<HttpContextBase>();
httpCtxStub.SetupGet(ctx => ctx.User).Returns(user);
var controllerCtx = new ControllerContext();
controllerCtx.HttpContext = httpCtxStub.Object;
sut.ControllerContext = controllerCtx;
然後調用您的操作並驗證返回結果是否爲RedirectResult。
此測試利用了隱式知識,當您使用空名稱創建GenericIdentity時,它將爲IsAuthenticated返回false。您可以考慮通過使用Mock<IIdentity>
來更明確地進行測試。
相關問題
- 1. 如何對使用springSecurityService的控制器進行單元測試?
- 2. 如何對zend動作控制器進行單元測試?
- 3. Controller.User是空單元測試
- 4. 使用依賴注入對控制器進行單元測試
- 5. 如何對此控制器進行單元測試?
- 6. 如何在mvc控制器中進行會話變量的單元測試
- 7. 如何對使用DotNetOpenId的ASP.NET MVC控制器進行單元測試?
- 8. 如何對使用環境變量的裝飾器進行單元測試?
- 9. 您如何使用EF SaveChanges對MVC控制器進行單元測試
- 10. 使用起訂量測試控制器操作方法的單元
- 11. 如何對使用ServiceStack的JsonServiceClient()的ASP.NET MVC操作進行單元測試?
- 12. 單元測試控制器調用IsAjaxRequest()的操作
- 13. 使用DB單元進行彈簧控制器集成測試
- 14. 使用控制器參數進行單元測試
- 15. 如何測試'新'控制器操作?
- 16. 當使用automapper時如何對單元測試控制器?
- 17. 如何使用$ scope對單元測試角控制器$ on?
- 18. 如何在操作中對具有私有方法的ASP.Net MVC控制器進行單元測試?
- 19. 如何使用System.Windows.Threading.Dispatcher對單元進行單元測試
- 20. Asp.Net的mvc單元測試的控制器操作
- 21. 使用Rspec進行控制器測試
- 22. 我的單元測試是不是抓我控制器操作
- 23. 單元測試控制器
- 24. 單元測試控制器
- 25. MVC控制器單元測試寫作
- 26. 如何對wxPython進行單元測試?
- 27. 如何對rxjs5進行單元測試?
- 28. 如何對Response.Redirect進行單元測試?
- 29. 如何對IDataErrorInfo進行單元測試?
- 30. 如何對Xtext進行單元測試
完美。答案仍然相關。+ 1 – joshmcode 2016-11-02 21:22:25