2013-03-14 19 views
23

kiểm tra đơn vị của tôi cho một ApiController sử dụng một số phương pháp giúp đỡ để nhanh chóng điều khiển:Thiết lập thuộc tính tài khoản cho một ApiController trong Unit Test

public static ResourcesController SetupResourcesController(HttpRequestMessage request, IResourceMetadataRepository repo, IUnitOfWorkService unitOfWorkService) 
{ 
    var config = new HttpConfiguration(); 
    var defaultRoute = config.Routes.MapHttpRoute(RouteNames.DefaultApi , "api/{controller}/{id}"); 
    var routeData = new HttpRouteData(defaultRoute, new HttpRouteValueDictionary { { "controller", "resources" } }); 

    var resourcesController = new ResourcesController(repo, unitOfWorkService) 
    { 
     ControllerContext = new HttpControllerContext(config, routeData, request), 
     Request = request 
    }; 
    resourcesController.Request.Properties.Add(HttpPropertyKeys.HttpRouteDataKey, routeData); 
    resourcesController.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; 

    // Compilation fail: The Property 'System.Web.Http.ApiController.User' has no setter. 
    resourcesController.User = myStubUserPrincipal; 

    return resourcesController; 
} 

Câu hỏi của tôi là: làm thế nào để thiết lập thuộc tính tài cho bộ điều khiển?

Tôi đã thử:

request.Properties.Add("MS_UserPrincipal", myStubUserPrincipal); 

Nhưng điều này không làm việc, hoặc (tài sản resourcesController.User vẫn null).

Trả lời

32

Đặt Thread.CurrentPrincipal và điều đó sẽ tự động khởi tạo thuộc tính User trong bộ điều khiển.

Đối với những người xem câu trả lời này, nhưng không biết cách đặt CurrentPrincipal.: This code được trích xuất từ ​​MSDN.

Thread.CurrentPrincipal = new GenericPrincipal 
(
    new GenericIdentity("Bob", "Passport"), 
    new[] {"managers", "executives"} 
); 
+0

Cảm ơn Pablo! Có vẻ quá đơn giản là đúng nhưng có; đặt thuộc tính Thread.CurrentPrincipal trong mã thiết lập thử nghiệm của tôi đã thực hiện thủ thuật! – JTech

+0

Tuyệt vời! Tôi đã tìm kiếm cách để giả mạo/giả mạo mọi thứ và đây là một cách đơn giản để làm điều đó. – Aligned

+3

Đối với những người nhìn thấy câu trả lời này, nhưng không có ý tưởng làm thế nào để thiết lập CurrentPrincipal. Mã này được trích xuất từ ​​MSDN. Thread.CurrentPrincipal = new GenericPrincipal (mới GenericIdentity ("Bob", "Passport"), new [] {"managers", "executives"}); http://msdn.microsoft.com/en-us/library/system.threading.thread.currentprincipal.aspx Thêm câu trả lời này vào câu trả lời của bạn nếu bạn muốn. – ruffen

8

Một cách sạch sẽ để thử đi IPrincipalHttpRequestContext, ví dụ sử dụng Moq:

var userMock = new Mock<IPrincipal>(); 
userMock.Setup(p => p.IsInRole("admin")).Returns(true); 
userMock.SetupGet(p => p.Identity.Name).Returns("tester"); 
userMock.SetupGet(p => p.Identity.IsAuthenticated).Returns(true); 

var requestContext = new Mock<HttpRequestContext>(); 
requestContext.Setup(x => x.Principal).Returns(userMock.Object); 

var controller = new ControllerToTest() 
{ 
    RequestContext = requestContext.Object, 
    Request = new HttpRequestMessage(), 
    Configuration = new HttpConfiguration() 
}; 
Các vấn đề liên quan