2009-04-16 43 views
40

嘲笑Controller.User我有一對夫婦ActionMethods的一個查詢Controller.User像這樣如何用最小起訂量

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

根據這一條件方便行事的作用。

我開始做這些方法測試的代碼是這樣

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

    Assert.IsNotNull(index); 
} 

和測試失敗,因爲Controller.User未設置。 有什麼想法?

回答

65

您需要模擬ControllerContext,HttpContextBase和最終IPrincipal來模擬Controller上的用戶屬性。使用Moq(v2)應該可以工作。

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

測試時,用戶是不是管理員的行爲是改變預期的userMock對象上設置返回false一樣簡單。

+8

在最新版本的Moq中,ExpectGet已被SetupGet取代。 – Slider345 2011-06-20 23:48:28

20

使用起訂量3.1版(和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'"); 
    } 

注意,沒有必要爲HttpContext的模擬,起訂量設置測試時提供支持性的嵌套。