2009-09-07 8 views
34

tengo una acción que se basa en User.Identity.Name para obtener el nombre de usuario del usuario actual para obtener una lista de sus órdenes:controlador de Acción Prueba que utiliza 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)); 
    } 

Ahora Estoy intentando escribir pruebas unitarias para esto, pero me quedo atascado sobre cómo proporcionar un simulacro para User.Identity.Name. Si ejecuto mi prueba tal como la tengo (sin simulacro de Usuario ...), obtengo una excepción nula.

¿Cuál es el enfoque correcto para esto? Estoy pensando que mi código de Acción no es bueno para las pruebas unitarias.

Respuesta

21

Una mejor manera de hacer esto sería pasar un argumento stringuserName (o un argumento IPrincipaluser, si necesita más información que sólo el nombre) a la ActionMethod, que se "inyecta" en una solicitud normal usando una ActionFilterAttribute. Cuando lo prueba, solo proporciona su propio objeto simulado, ya que el código del filtro de acción no se ejecutará (en la mayoría de los casos, hay formas de hacerlo, si usted lo desea específicamente ...)

Kazi Manzur Rashid describe esto en detalle bajo el punto 7 en un excellent blog post.

+0

Genial. Tengo que buscar más en ActionFilters ... Gracias. –

+0

A menudo me burlo de IPrincipal para mis pruebas. Me permite probar la información del usuario (nombre de usuario) pero también la autorización (User.Identity.IsInRole). –

+1

Yo también. Por otro lado, burlarse de IPrincipal solo para obtener acceso al nombre de usuario actual del usuario - y * nada * más - está al borde de la exageración ... :) –

62

Usted puede utilizar este código

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

Utiliza Moq marco de burla, sino que usted puede usar lo que quiera.

+0

Para cualquier otra persona, como yo, que se preguntaba: este ejemplo de código utiliza [Moq] (https://code.google. com/p/moq /). –

+2

En WebAPI me gustó esto '' MyController controller = new MyController(); controller.User = new GenericPrincipal (new GenericIdentity (username, "Passport"), new [] {"tester "});' ' – Ravi

+0

@Ravi How ? [Controller.User no se puede establecer] (https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.user) (aunque esto podría haber cambiado en los últimos 2.5 años) – Wolfzoon

Cuestiones relacionadas