2009-09-07 8 views
34

Mam działań, które opiera się na User.Identity.Name aby uzyskać nazwę użytkownika bieżącego użytkownika, aby uzyskać listę rozkazów:Testowanie działania kontroler, który wykorzystuje User.Identity.Name

public ActionResult XLineas() 
    { 
     ViewData["Filtre"] = _options.Filtre; 
     ViewData["NomesPendents"] = _options.NomesPendents; 
     return View(_repository.ObteLiniesPedido(User.Identity.Name,_options.Filtre,_options.NomesPendents)); 
    } 

Teraz Próbuję napisać testy jednostkowe, ale utknąłem na tym, jak dostarczyć Mock dla User.Identity.Name. Jeśli uruchomię test tak, jak go mam (bez fałszywej próby dla użytkownika ...), otrzymuję wyjątek Null ..

Jakie jest właściwe podejście do tego? Myślę, że mój kod Action nie nadaje się do testów jednostkowych.

Odpowiedz

21

Lepszym sposobem osiągnięcia tego celu byłoby przekazać string argumentu userName (lub IPrincipal argumentu user, jeśli potrzebują Państwo więcej informacji niż tylko nazwa) do ActionMethod, co ty „wstrzyknięcie” w normalnym żądanie stosując ActionFilterAttribute. Podczas testowania, po prostu dostarczasz swój fałszywy obiekt, ponieważ kod filtra akcji nie działa (w większości przypadków - są sposoby, aby konkretnie chcieć ...)

Kazi Manzur Rashid opisuje to w szczegóły w pkt 7 w excellent blog post.

+0

Świetnie. Muszę zagłębić się w ActionFiltry ... Dzięki. –

+0

Często kpię z IPrincipala za moje testy. Pozwala mi to przetestować informacje użytkownika (nazwę użytkownika), ale także autoryzację (User.Identity.IsInRole). –

+1

Podobnie jak ja. Z drugiej strony, kpina z IPrincipala tylko po to, by uzyskać dostęp do nazwy użytkownika bieżącego użytkownika - i * nic * innego - jest na granicy przesady ... :) –

62

Można użyć tego kodu

public SomeController CreateControllerForUser(string userName) 
{ 
    var mock = new Mock<ControllerContext>(); 
    mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName); 
    mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true); 

    var controller = new SomeController(); 
    controller.ControllerContext = mock.Object; 

    return controller; 
} 

Wykorzystuje Moq szyderczy ramy, ale na pewno można użyć cokolwiek chcesz.

+0

Dla każdego, kto mnie zastanawiał: ten przykładowy kod używa [Moq] (https://code.google. com/p/moq /). –

+2

W WebAPI podoba mi się ten '' Kontroler MyController = nowy sterownik MyController(); controller.User = nowy GenericPrincipal (nowy GenericIdentity (nazwa użytkownika, "Passport"), nowy [] {"tester "});' ' – Ravi

+0

@Ravi How ? [Controller.User nie jest ustawialny] (https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.user) (choć mogło to ulec zmianie w ciągu ostatnich 2,5 roku) – Wolfzoon

Powiązane problemy