2013-03-14 10 views
23

moich testów jednostkowych o wydanie ApiController wykorzystuje kilka metod pomocników instancję kontrolera:Ustaw właściwość użytkownika dla ApiController w jednostce testowej

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

Moje pytanie brzmi: jak ustawić właściwość użytkownika do kontrolera?

Próbowałem:

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

Ale to nie działa albo (właściwość resourcesController.User pozostaje null).

Odpowiedz

32

Ustaw Thread.CurrentPrincipal, który automatycznie zainicjuje właściwość User w kontrolerze.

Dla osób, które widzą tę odpowiedź, ale nie mają pojęcia, jak ustawić CurrentPrincipal.: This code jest wyodrębniony z MSDN.

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

Dzięki Pablo! Wydaje się zbyt proste, aby mogło być prawdziwe, ale tak; ustawienie właściwości Thread.CurrentPrincipal w moim kodzie konfiguracji testu zrobiło lewę! – JTech

+0

Świetnie! Szukałem, jak kpić/fałszować wszystko i jest to prosty sposób na zrobienie tego. – Aligned

+3

Dla osób, które widzą tę odpowiedź, ale nie mają pojęcia, jak ustawić CurrentPrincipal. Ten kod jest pobierany z MSDN. Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("Bob", "Passport"), new [] {"managers", "executive"}); http://msdn.microsoft.com/en-us/library/system.threading.thread.currentprincipal.aspx Dodaj to do swojej odpowiedzi, jeśli chcesz. – ruffen

8

Czystsze sposobem byłoby kpić z dala IPrincipal i HttpRequestContext, na przykład stosując Min:

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() 
}; 
Powiązane problemy