依赖于HTTPContext的MVC测试操作

时间:2011-09-26 07:34:47

标签: c# model-view-controller testing httpcontext

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

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

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

这是一个推荐的approuch还是有人有任何其他的想法,我不必将我的静态类更改为实例吗?

2 个答案:

答案 0 :(得分: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。
  5. 代码可能是这样的:

    [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;
        .....
        ......
    
    }
    

答案 1 :(得分:0)

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