2009-04-16 23 views
40

Tengo un par de ActionMethods que consulta la Controller.User por su papel como ésteCómo se burlan Controller.User usando moq

bool isAdmin = User.IsInRole("admin"); 

actuar convenientemente en esa condición.

estoy empezando a hacer pruebas para estos métodos con el código como este

[TestMethod] 
public void HomeController_Index_Should_Return_Non_Null_ViewPage() 
{ 
    HomeController controller = new HomePostController(); 
    ActionResult index = controller.Index(); 

    Assert.IsNotNull(index); 
} 

y que prueba falla porque Controller.User no está establecido. ¿Alguna idea?

Respuesta

65

Necesita simular el ControllerContext, HttpContextBase y finalmente IPrincipal para simular la propiedad del usuario en el controlador. Usando Moq (v2) algo en las siguientes líneas debería funcionar.

[TestMethod] 
    public void HomeControllerReturnsIndexViewWhenUserIsAdmin() { 
     var homeController = new HomeController(); 

     var userMock = new Mock<IPrincipal>(); 
     userMock.Expect(p => p.IsInRole("admin")).Returns(true); 

     var contextMock = new Mock<HttpContextBase>(); 
     contextMock.ExpectGet(ctx => ctx.User) 
        .Returns(userMock.Object); 

     var controllerContextMock = new Mock<ControllerContext>(); 
     controllerContextMock.ExpectGet(con => con.HttpContext) 
          .Returns(contextMock.Object); 

     homeController.ControllerContext = controllerContextMock.Object; 
     var result = homeController.Index(); 
     userMock.Verify(p => p.IsInRole("admin")); 
     Assert.AreEqual(((ViewResult)result).ViewName, "Index"); 
    } 

probar el comportamiento cuando el usuario no es un administrador es tan simple como cambiar la expectativa puesta en el objeto userMock para volver falsa.

+8

En las últimas versiones de Moq, ExpectGet ha sido reemplazado por SetupGet. – Slider345

+0

¿Hay alguna manera de hacerlo si está utilizando ClaimsPrincipal en el constructor del controlador? – russelrillema

20

Usando Moq versión 3.1 (y NUnit):

[Test] 
    public void HomeController_Index_Should_Return_Non_Null_ViewPage() 
    { 
     // Assign: 
     var homeController = new HomeController(); 

     Mock<ControllerContext> controllerContextMock = new Mock<ControllerContext>(); 
     controllerContextMock.Setup(
      x => x.HttpContext.User.IsInRole(It.Is<string>(s => s.Equals("admin"))) 
      ).Returns(true); 
     homeController.ControllerContext = controllerContextMock.Object; 

     // Act: 
     ActionResult index = homeController.Index(); 

     // Assert: 
     Assert.IsNotNull(index); 
     // Place other asserts here... 
     controllerContextMock.Verify(
      x => x.HttpContext.User.IsInRole(It.Is<string>(s => s.Equals("admin"))), 
      Times.Exactly(1), 
      "Must check if user is in role 'admin'"); 
    } 

en cuenta que no hay necesidad de crear simulacro de HttpContext, Moq apoya anidamiento de propiedades cuando la creación de la prueba.

Cuestiones relacionadas