2013-03-14 7 views
23

mio test di unità per un ApiController utilizza alcuni metodi aiutanti per creare un'istanza del controllo:immobili Impostazione utente per un ApiController in unità di prova

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; 
} 

La mia domanda è: come impostare la proprietà utente per il controllore?

ho provato:

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

Ma questo non funziona neanche (la proprietà resourcesController.User rimane nullo).

risposta

32

Impostare il Thread.CurrentPrincipal e questo inizializzerà automaticamente la proprietà User nel controller.

Per le persone che vedono questa risposta, ma non hanno idea di come impostare CurrentPrincipal.: This code viene estratto da MSDN.

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

Grazie Pablo! Sembra troppo semplice per essere vero ma sì; l'impostazione della proprietà Thread.CurrentPrincipal all'interno del mio codice di installazione di prova ha funzionato! – JTech

+0

Ottimo! Stavo cercando su come deridere/fingere tutto e questo è un modo semplice per farlo. – Aligned

+3

Per le persone che vedono questa risposta, ma non hanno idea di come impostare CurrentPrincipal. Questo codice è stato estratto da MSDN. Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("Bob", "Passport"), new [] {"managers", "executives"}); http://msdn.microsoft.com/en-us/library/system.threading.thread.currentprincipal.aspx Aggiungi questo alla tua risposta, se vuoi. – ruffen

8

un modo più pulito sarebbe quello di prendere in giro via IPrincipal e HttpRequestContext, ad esempio utilizzando 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() 
};