2009-04-16 15 views
40

Mam parę ActionMethods który odpytuje Controller.User dla jego roli jak tenJak drwić Controller.User użyciu MOQ

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

działającego dogodnie pod tym warunkiem.

Zaczynam robić testy na tych metod z kodem jak ten

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

    Assert.IsNotNull(index); 
} 

i że test nie powiedzie się, ponieważ Controller.User nie jest ustawiony. Każdy pomysł?

Odpowiedz

65

Należy wyśmiać Kontrast ControllerContext, HttpContextBase i wreszcie IPrincipal, aby sfałszować właściwość użytkownika na kontrolerze. Używając Moq (v2), powinno działać coś z następujących linii.

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

Testowanie zachowania, gdy użytkownik nie jest administratorem jest tak proste, jak zmiana oczekiwanie ustawiony na obiekcie userMock do return false.

+8

W najnowszych wersjach Moq, ExpectGet został zastąpiony przez SetupGet. – Slider345

+0

Jakikolwiek sposób to zrobić, jeśli korzystasz z ClaimsPrincipal w konstruktorze kontrolera? – russelrillema

20

Korzystanie Min wersji 3.1 (i 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'"); 
    } 

Zauważ, że nie ma potrzeby tworzenia makiety dla HttpContext, Moq podczas konfigurowania test obsługuje zagnieżdżanie właściwości.

Powiązane problemy