2009-04-16 11 views
40

J'ai deux ou trois ActionMethods qui interroge le Controller.User pour son rôle comme celui-ciComment se moquer Controller.User en utilisant moq

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

agissant commodément à cette condition.

Je commence à faire des tests pour ces méthodes avec le code suivant

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

    Assert.IsNotNull(index); 
} 

et que le test échoue parce Controller.User n'est pas réglé. Une idée?

Répondre

65

Vous devez simuler le ControllerContext, HttpContextBase et enfin IPrincipal pour simuler la propriété de l'utilisateur sur le contrôleur. En utilisant Moq (v2) quelque chose le long des lignes suivantes devrait fonctionner.

[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"); 
    } 

Test du comportement lorsque l'utilisateur n'est pas un administrateur est aussi simple que de changer l'attente définie sur l'objet de userMock return false.

+8

Dans les dernières versions de Moq, ExpectGet a été remplacé par SetupGet. – Slider345

+0

Un moyen de le faire si vous utilisez ClaimsPrincipal dans le constructeur du contrôleur? – russelrillema

20

En utilisant la version 3.1 Moq (et 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'"); 
    } 

avis qu'il n'y a pas besoin de créer pour faux HttpContext, Moq prend en charge l'imbrication des propriétés lors de la mise en place du test.

Questions connexes