51 votes

Comment se moquer de Controller.User en utilisant moq

J'ai un couple de ActionMethods qui interroge le Controller.User pour son rôle comme celui-ci

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

agissant commodément à cette condition.

Je commence à faire des tests pour ces méthodes avec un code comme celui-ci

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

    Assert.IsNotNull(index);
}
 

et ce test échoue car Controller.User n'est pas défini. Une idée?

75voto

John Foster Points 5411

Vous devez simuler ControllerContext, HttpContextBase et enfin IPrincipal pour simuler la propriété de l'utilisateur sur Controller. En utilisant Moq (v2), quelque chose dans les 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");
    }
 

Tester le comportement lorsque l'utilisateur n'est pas un administrateur est aussi simple que de modifier l'attente définie sur l'objet userMock pour qu'elle renvoie false.

25voto

Eirik W Points 1173

Utilisation de Moq version 3.1 (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'");
    }
 

Notez qu'il n'est pas nécessaire de créer une maquette pour HttpContext, Moq prend en charge l'imbrication de propriétés lors de la configuration du test.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X