2011-09-26 62 views
1

我有一个需要提供操作测试的项目。我的approuch一直在确保操作不依赖于任何他们没有收到的参数,从而使用ValueProviders和ModelBinder。因此,我会通过HTTPContextBase等MVC依赖于HTTPContext的测试操作

但是,我现在有一个动作,它使用静态类是HTTPContext的包装来访问会话和身份。因此,似乎我必须模拟出HTTPContext来测试此操作。我想不是太复杂,但它只是感觉不对。

我的直觉是应该重新开发静态类,以便使用HTTPSessionStateBase和IPrinicple实例化并将它们用作内部存储。然后,我可以在动作中从动作参数中实例化这个包装器,使动作和包装器类更友好。

这是一个建议approuch或没有任何人有任何其他的想法,我是不是会改变我的静态类为实例吗?

回答

0

我强烈建议使用MvcContrib - testhelpers 了解如何从CodePlex
使用您可以从nuget CodePlex从
祝你好运下载,也可以直接!

+0

有一个快速浏览一下他们,特别是我的情况,看来你是能够建立一个控制范围内,但不会出现是初始化ASP的HTTPContext.Current的任何东西。因此,当我的动作调用静态包装类时,它依次尝试访问HTTPContext.Current.Session,我得到一个错误。我想我只需要经历在我的测试中初始化HTTPContext.Current的痛苦? – ricardo

+0

@ricardo它看起来像你不使用DI。注入httpContext并且所有的问题都会消失......使用静态httpContext.Current是一个错误,你可以在你的情况下看到它。祝你好运! – gdoron

1

我认为使用Moq来模拟一个HttpContext只是你可能想要尝试的方式。

[TestMethod] 
public void Test() 
{ 

    var context = new Mock<HttpContextBase>(); 
    var request = new Mock<HttpRequestBase>(); 
    context.Setup(c => c.Request).Returns(request.Object); 

    HomeController controller = new HomeController(); 

    controller.ControllerContext = new ControllerContext(context , new RouteData(), controller); 

    .... 
    ........... 
} 




更新时间:
如果您想嘲笑HttpSession中(如在评论中提及gdoron)的情况。它并不是很复杂,因为你是Mocking,并不意味着你必须构建完整的,真实的对象及其所有属性。

假设您的控制器将

  1. 检查是否用户进行身份验证。
  2. 获取标识名称。
  3. 从Session [“key”]中获取一个值。
  4. 操纵cookie。

的代码可能是这样的:

[TestMethod] 
public void Test() 
{ 
    ...... 
    ......... 
    var mockedControllerContext = new Mock<ControllerContext>(); 
    mockedControllerContext.SetupGet(p => p.HttpContext.Session["key"]).Returns("A value in session"); 
    mockedControllerContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);  
    mockedControllerContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("An identity name"); 
    mockedControllerContext.SetupGet(p => p.HttpContext.Response.Cookies).Returns(new HttpCookieCollection()); 

    HomeController controller = new HomeController(); 
    controller.ControllerContext = mockedControllerContext.Object; 
    ..... 
    ...... 

} 
+0

实现模拟会话时所写的内容非常复杂! – gdoron

+0

问题是Contoller的HttpContext是从静态ASP.NET HttpContext中设置的。因此,简单地构建HttpContextBase并将其附加到Controller的上下文不会影响静态HttpContext。我的动作调用一个静态包装器,它无法访问ControllerContext并直接访问ASP.NET HttpContext。除非我误解了某些东西,否则我觉得这个设计是有缺陷的,静态包装应该被重新开发为一个采用控制器的HttpContext的实例,然后我可以嘲笑它的生活......如果我选择。 – ricardo

+0

我认为你是对的。既然你选择了静态保存的东西。你失去了灵活性(但它可能会节省一些资源的好处) –