2009-04-16 86 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的模拟,起订量设置测试时提供支持性的嵌套。