2009-09-07 9 views
34

Ho un'azione che si basa su User.Identity.Name per ottenere il nome utente dell'utente corrente per ottenere un elenco dei suoi ordini:regolatore prova di azione che utilizza 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)); 
    } 

Ora Sto provando a scrivere test unitari per questo, ma rimango bloccato su come fornire un Mock per User.Identity.Name. Se eseguo il test come ho fatto io (senza simulazione per Utente ...), ottengo un'eccezione Null ....

Qual è l'approccio corretto per questo? Sto pensando che il mio codice di azione non è buono per i test unitari.

risposta

21

Un modo migliore per farlo sarebbe quello di passare un string argomento userName (o un IPrincipal argomento user, se avete bisogno di ulteriori informazioni non solo il nome) alla ActionMethod, che si "iniettare" in una richiesta normale utilizzando un ActionFilterAttribute. Quando lo provi, devi solo fornire il tuo oggetto fittizio, poiché il codice del filtro azione non verrà eseguito (nella maggior parte dei casi, ci sono modi per, se vuoi specificamente ...)

Kazi Manzur Rashid descrive questo in dettaglio al punto 7 in un excellent blog post.

+0

Grande. Devo guardare più in ActionFilters ... Grazie. –

+0

Spesso simulo IPrincipal per i miei test. Mi permette di testare le informazioni dell'utente (username) ma anche l'autorizzazione (User.Identity.IsInRole). –

+1

Anche io. D'altra parte, il mocking di IPrincipal solo per ottenere l'accesso al nome utente dell'utente corrente - e * nothing * else - è al limite dell'overkill ... :) –

62

È possibile utilizzare questo codice

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

Esso utilizza Moq quadro beffardo, ma che si può usare qualsiasi cosa che ti piace.

+0

Per chiunque altro, come me, che si stava chiedendo: questo esempio di codice usa [Moq] (https://code.google. com/p/moq /). –

+2

In WebAPI mi sono comportato così '' Controller MyController = nuovo MyController(); controller.Utente = nuovo GenericPrincipal (nuovo GenericIdentity (username, "Passport"), nuovo [] {"tester "});' ' – Ravi

+0

@Ravi How ? [Controller.Utente non è impostabile] (https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.user) (anche se questo potrebbe essere cambiato negli ultimi 2,5 anni) – Wolfzoon

Problemi correlati